aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2019-03-06 14:41:00 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2019-05-22 12:09:09 +0200
commitd894c48660a573f257f76fe075e512415fdd0f91 (patch)
treeb077999723cc6724c4ab141334af0cb00577ba91 /docs
parente9bd7d49bdc8c630cca3bf4cc02c437841b6aaf6 (diff)
downloadmeson-d894c48660a573f257f76fe075e512415fdd0f91.zip
meson-d894c48660a573f257f76fe075e512415fdd0f91.tar.gz
meson-d894c48660a573f257f76fe075e512415fdd0f91.tar.bz2
new module "sourceset" to match source file lists against configuration data
In QEMU a single set of source files is built against many different configurations in order to generate many executable. Each executable includes a different but overlapping subset of the source files; some of the files are compiled separately for each output, others are compiled just once. Using Makefiles, this is achieved with a complicated mechanism involving a combination of non-recursive and recursive make; Meson can do better, but because there are hundreds of such conditional rules, it's important to keep meson.build files brief and easy to follow. Therefore, this commit adds a new module to satisfy this use case while preserving Meson's declarative nature. Configurations are mapped to a configuration_data object, and a new "source set" object is used to store all the rules, and then retrieve the desired set of sources together with their dependencies. The test case shows how extract_objects can be used to satisfy both cases, i.e. when the object files are shared across targets and when they have to be separate. In the real-world case, a project would use two source set objects for the two cases and then do "executable(..., sources: ... , objects: ...)". The next commit adds such an example.
Diffstat (limited to 'docs')
-rw-r--r--docs/markdown/SourceSet-module.md196
-rw-r--r--docs/markdown/snippets/sourceset.md8
-rw-r--r--docs/sitemap.txt1
3 files changed, 205 insertions, 0 deletions
diff --git a/docs/markdown/SourceSet-module.md b/docs/markdown/SourceSet-module.md
new file mode 100644
index 0000000..fee643a
--- /dev/null
+++ b/docs/markdown/SourceSet-module.md
@@ -0,0 +1,196 @@
+---
+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])
+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.
+
+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` 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
+
+#### `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
diff --git a/docs/markdown/snippets/sourceset.md b/docs/markdown/snippets/sourceset.md
new file mode 100644
index 0000000..7c09eb5
--- /dev/null
+++ b/docs/markdown/snippets/sourceset.md
@@ -0,0 +1,8 @@
+## New `sourceset` module
+
+A new module, `sourceset`, was added to help building many binaries
+from the same source files. Source sets associate source files and
+dependencies to keys in a `configuration_data` object or a dictionary;
+they then take multiple `configuration_data` objects or dictionaries,
+and compute the set of source files and dependencies for each of those
+configurations.
diff --git a/docs/sitemap.txt b/docs/sitemap.txt
index 2e6eb68..449f08b 100644
--- a/docs/sitemap.txt
+++ b/docs/sitemap.txt
@@ -43,6 +43,7 @@ index.md
Qt5-module.md
RPM-module.md
Simd-module.md
+ SourceSet-module.md
Windows-module.md
Cuda-module.md
Kconfig-module.md