diff options
author | Tristan Van Berkom <tristan.vanberkom@codethink.co.uk> | 2020-04-16 20:04:33 +0900 |
---|---|---|
committer | Tristan Van Berkom <tristan.vanberkom@codethink.co.uk> | 2020-04-17 20:58:24 +0900 |
commit | 6b9619b0cbb69310f2543605500a4b82e315738f (patch) | |
tree | fe7a52bc6edae7e5fe4b75cb72601f85da8ffd60 /doc/source | |
parent | b2a8fc10e286cf0293ae3f69782f9b5e86b49da0 (diff) | |
download | buildstream-6b9619b0cbb69310f2543605500a4b82e315738f.tar.gz |
doc/examples/filtering: Added a new user guide entry about filter elements
Diffstat (limited to 'doc/source')
-rw-r--r-- | doc/source/handling-files/filtering.rst | 203 | ||||
-rw-r--r-- | doc/source/using_handling_files.rst | 1 |
2 files changed, 204 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. diff --git a/doc/source/using_handling_files.rst b/doc/source/using_handling_files.rst index 8951764e0..58e8a75a2 100644 --- a/doc/source/using_handling_files.rst +++ b/doc/source/using_handling_files.rst @@ -8,3 +8,4 @@ handling of files. :maxdepth: 1 handling-files/composition.rst + handling-files/filtering.rst |