summaryrefslogtreecommitdiff
path: root/doc/source/handling-files/filtering.rst
diff options
context:
space:
mode:
Diffstat (limited to 'doc/source/handling-files/filtering.rst')
-rw-r--r--doc/source/handling-files/filtering.rst203
1 files changed, 203 insertions, 0 deletions
diff --git a/doc/source/handling-files/filtering.rst b/doc/source/handling-files/filtering.rst
new file mode 100644
index 000000000..27cdfe679
--- /dev/null
+++ b/doc/source/handling-files/filtering.rst
@@ -0,0 +1,203 @@
+
+
+.. _handling_files_filtering:
+
+Filtering
+=========
+In this chapter we will explore how to *filter* the files in an artifact
+using the :mod:`filter <elements.filter>` element, such that an element might
+depend on a subset of the files provided by a filtered element.
+
+.. note::
+
+ This example is distributed with BuildStream
+ in the `doc/examples/filtering
+ <https://gitlab.com/BuildStream/buildstream/tree/master/doc/examples/filtering>`_
+ subdirectory.
+
+
+Overview
+--------
+In some cases, it can be useful to depend on a *subset* of the files of an
+element, without depending on the entire element.
+
+One scenario where filtering can be useful, is when you have an element which
+will build differently depending on what is present in the system where it is
+building. In an edge case where a module fails to offer configure time options to
+disable an unwanted feature or behavior in the build, you might use
+:mod:`filter <elements.filter>` elements to ensure that special header files or
+pkg-config files are *filtered out* from the system at build time, such that
+the unwanted behavior cannot be built.
+
+In many ways, a :mod:`filter <elements.filter>` element is like a
+:mod:`compose <elements.compose>` element, except that it operates on a single
+:ref:`build dependency <format_build_depends>`, without compositing the filtered
+element with its :ref:`runtime dependencies <format_runtime_depends>`.
+
+.. tip::
+
+ The :mod:`filter <elements.filter>` element is special in the sense
+ that it acts as a *window* into it's primary
+ :ref:`build dependency <format_build_depends>`.
+
+ As such, :ref:`opening a workspace <invoking_workspace_open>` on a
+ :mod:`filter <elements.filter>` element will result in opening a
+ workspace on the element which it filters. Any other workspace
+ commands will also be forwarded directly to the filtered element.
+
+
+Project structure
+-----------------
+This example again expands on the example presenting in the chapter about
+:ref:`integration commands <tutorial_integration_commands>`. In this case
+we will modify ``libhello.bst`` such that it produces a new file which,
+if present, will affect the behavior of it's reverse dependency ``hello.bst``.
+
+Let's first take a look at how the sources have changed.
+
+
+``files/hello/Makefile``
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. literalinclude:: ../../examples/filtering/files/hello/Makefile
+ :language: Makefile
+
+Now we have our Makefile discovering the system defined default
+person to say hello to.
+
+
+``files/hello/hello.c``
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. literalinclude:: ../../examples/filtering/files/hello/hello.c
+ :language: c
+
+If this program has been given a ``DEFAULT_PERSON``, then it will
+say hello to that person in the absence of any argument.
+
+
+``project.conf``
+~~~~~~~~~~~~~~~~
+
+.. literalinclude:: ../../examples/filtering/project.conf
+ :language: yaml
+
+Here, we've added a :ref:`project option <project_options>` to decide
+whether to use the :mod:`filter <elements.filter>` element or not.
+
+This is merely for brevity, so that we can demonstrate the behavior
+of depending on the filtered element without defining two separate versions
+of the ``hello.bst`` element.
+
+
+``elements/libhello.bst``
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. literalinclude:: ../../examples/filtering/elements/libhello.bst
+ :language: yaml
+
+We've added some :ref:`split rules <public_split_rules>` here to declare
+a new *split domain* named ``defaults``, and we've added the new
+``default-person.txt`` file to this *domain*.
+
+
+``elements/libhello-filtered.bst``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. literalinclude:: ../../examples/filtering/elements/libhello-filtered.bst
+ :language: yaml
+
+And we've added a new :mod:`filter <elements.filter>` element to the project
+which uses the ``exclude`` option of the filter configuration.
+
+This is essentially a statement that any files mentioned in the the
+``defaults`` *domain* of the ``libhello.bst`` element should be excluded from
+the resulting artifact.
+
+.. important::
+
+ Notice that you need to explicitly declare any
+ :ref:`runtime dependencies <format_runtime_depends>` which are required by the
+ resulting artifact of a :mod:`filter <elements.filter>` element, as runtime
+ dependencies of the build dependency are not transient.
+
+
+``elements/hello.bst``
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. literalinclude:: ../../examples/filtering/elements/hello.bst
+ :language: yaml
+
+Here we've merely added a :ref:`conditional statement <format_directives_conditional>`
+which allows us to test the ``hello.bst`` element depending on the filtered
+version of the library, or the unfiltered version.
+
+
+Using the project
+-----------------
+Let's just skip over building the ``hello.bst`` element with the
+``use_filter`` option both ``True`` and ``False``, these elements
+are easily built with :ref:`bst build <invoking_build>` as such:
+
+.. code:: shell
+
+ bst --option use_filter True build hello.bst
+ bst --option use_filter False build hello.bst
+
+
+Observing the artifacts
+~~~~~~~~~~~~~~~~~~~~~~~
+Let's take a look at the built artifacts.
+
+
+``libhello.bst``
+''''''''''''''''
+
+.. raw:: html
+ :file: ../sessions/filtering-list-contents-libhello.html
+
+Here we can see the full content of the ``libhello.bst`` artifact.
+
+
+``libhello-filtered.bst``
+'''''''''''''''''''''''''
+
+.. raw:: html
+ :file: ../sessions/filtering-list-contents-libhello-filtered.html
+
+Here we can see that the ``default-person.txt`` file has been filtered
+out of the ``libhello.bst`` artifact when creating the ``libhello-filtered.bst``
+artifact.
+
+
+Running hello.bst
+~~~~~~~~~~~~~~~~~
+Now if we run the program built by ``hello.bst`` in either build
+modes, we can observe the expected behavior.
+
+
+Run ``hello.bst`` built directly against ``libhello.bst``
+'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+.. raw:: html
+ :file: ../sessions/filtering-shell-without-filter.html
+
+Here we can see that the hello world program is using the system
+configured default person to say hello to.
+
+
+Run ``hello.bst`` built against ``libhello-filtered.bst``
+'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+.. raw:: html
+ :file: ../sessions/filtering-shell-with-filter.html
+
+And now we're reverting to the behavior we have when no
+system configured default person was installed at build time.
+
+
+Summary
+-------
+In this chapter, we've introduced the :mod:`filter <elements.filter>`
+element which allows one to filter the output of an element and
+effectively create a dependency on a subset of an element's files.