---
short-description: Source set module
authors:
    - name: Paolo Bonzini
      email: pbonzini@redhat.com
      years: [2019]
...

# Source set module

This module provides support for building many targets against a
single set of files; the choice of which files to include in each
target depends on the contents of a dictionary or a
`configuration_data` object. The module can be loaded with:

```meson
ssmod = import('sourceset')
```

A simple example of using the module looks like this:

```meson
ss = ssmod.source_set()
# Include main.c unconditionally
ss.add(files('main.c'))
# Include a.c if configuration key FEATURE1 is true
ss.add(when: 'FEATURE1', if_true: files('a.c'))
# Include zlib.c if the zlib dependency was found, and link zlib
# in the executable
ss.add(when: zlib, if_true: files('zlib.c'))
# many more rules here...
ssconfig = ss.apply(config)
executable('exe', sources: ssconfig.sources(),
           dependencies: ssconfig.dependencies())
```

and it would be equivalent to

```meson
sources = files('main.c')
dependencies = []
if config['FEATURE1'] then
    sources += [files('a.c')]
endif
if zlib.found() then
    sources += [files('zlib.c')]
    dependencies += [zlib]
endif
# many more "if"s here...
executable('exe', sources: sources, dependencies: dependencies)
```

Sourcesets can be used with a single invocation of the `apply` method,
similar to the example above, but the module is especially useful when
multiple executables are generated by applying the same rules to many
different configurations.

*Added 0.51.0*

## Functions

### `source_set()`

```meson
ssmod.source_set()
```

Create and return a new source set object.

**Returns**: a [source set][`source_set` object]

## `source_set` object

The `source_set` object provides methods to add files to a source set
and to query it. The source set becomes immutable after any method but
`add` is called.

### Methods

#### `add()`

```meson
source_set.add([when: varnames_and_deps],
               [if_true: sources_and_deps],
               [if_false: list_of_alt_sources_and_deps])
source_set.add(sources_and_deps)
```

Add a *rule* to a source set. A rule determines the conditions under
which some source files or dependency objects are included in a build
configuration. All source files must be present in the source tree or
they can be created in the build tree via `configure_file`,
`custom_target` or `generator`.

`varnames_and_deps` is a list of conditions for the rule, which can be
either strings or dependency objects (a dependency object is anything
that has a `found()` method). If *all* the strings evaluate to true
and all dependencies are found, the rule will evaluate to true;
`apply()` will then include the contents of the `if_true` keyword
argument in its result. Otherwise, that is if any of the strings in
the positional arguments evaluate to false or any dependency is not
found, `apply()` will instead use the contents of the `if_false`
keyword argument. *Since 1.11.0* Dependencies in `if_false` are supported.

Dependencies can also appear in `sources_and_deps`. In this case, a
missing dependency will simply be ignored and will *not* disable the
rule, similar to how the `dependencies` keyword argument works in
build targets.

**Note**: It is generally better to avoid mixing source sets and
disablers. This is because disablers will cause the rule to be dropped
altogether, and the `list_of_alt_sources_and_deps` would not be taken into
account anymore.

#### `add_all()`

```meson
source_set.add_all(when: varnames_and_deps,
                   if_true: [source_set1, source_set2, ...])
source_set.add_all(source_set1, source_set2, ...)
```

Add one or more source sets to another.

For each source set listed in the arguments, `apply()` will consider
their rules only if the conditions in `varnames_and_deps` are
evaluated positively. For example, the following:

```meson
sources_b = ssmod.source_set()
sources_b.add(when: 'HAVE_A', if_true: 'file.c')
sources = ssmod.source_set()
sources.add_all(when: 'HAVE_B', if_true: sources_b)
```

is equivalent to:

```meson
sources = ssmod.source_set()
sources.add(when: ['HAVE_A', 'HAVE_B'], if_true: 'file.c')
```

#### `all_sources()`

```meson
list source_set.all_sources(...)
```

Returns a list of all sources that were placed in the source set using
`add` (including nested source sets) and that do not have a not-found
dependency. If a rule has a not-found dependency, only the `if_false`
sources are included (if any).

**Returns**: a list of file objects

#### `all_dependencies()` *(since 0.52.0)*

```meson
list source_set.all_dependencies(...)
```

Returns a list of all dependencies that were placed in the source set
using `add` (including nested source sets) and that were found.

**Returns**: a list of dependencies

#### `apply()`

```meson
source_files source_set.apply(conf_data[, strict: false])
```

Match the source set against a dictionary or a `configuration_data`
object and return a *source configuration* object. A source
configuration object allows you to retrieve the sources and
dependencies for a specific configuration.

By default, all the variables that were specified in the rules have to
be present in `conf_data`. However, in some cases the convention is
that `false` configuration symbols are absent in `conf_data`; this is
the case for example when the configuration was loaded from a Kconfig
file. In that case you can specify the `strict: false` keyword
argument, which will treat absent variables as false.

**Returns**: a [source configuration][`source_configuration` object]

## `source_configuration` object

The `source_configuration` object provides methods to query the result of an
`apply` operation on a source set.

### Methods

#### `sources()`

```meson
source_config.sources()
```

Return the source files corresponding to the applied configuration.

**Returns**: a list of file objects

#### `dependencies()`

```meson
source_config.dependencies()
```

Return the dependencies corresponding to the applied configuration.

**Returns**: a list of dependency objects
