path: root/DOCS/waf-buildsystem.rst
diff options
authorStefano Pigozzi <>2013-07-16 13:28:28 +0200
committerStefano Pigozzi <>2013-11-21 21:22:36 +0100
commit7e2edad8efea55e8df1faa695d1389ef4e326d7c (patch)
treef9662620b8ecaf50f6c67804dd0d99d00d85fe5b /DOCS/waf-buildsystem.rst
parent0cb9227a73f03a6ecdf71e837c7c33c823b194b4 (diff)
switch the build system to waf
This commit adds a new build system based on waf. configure and Makefile are deprecated effective immediately and someday in the future they will be removed (they are still available by running ./old-configure). You can find how the choice for waf came to be in `DOCS/waf-buildsystem.rst`. TL;DR: we couldn't get the same level of abstraction and customization with other build systems we tried (CMake and autotools). For guidance on how to build the software now, take a look at and the cross compilation guide. CREDITS: This is a squash of ~250 commits. Some of them are not by me, so here is the deserved attribution: - @wm4 contributed some Windows fixes, renamed configure to old-configure and contributed to the bootstrap script. Also, GNU/Linux testing. - @lachs0r contributed some Windows fixes and the bootstrap script. - @Nikoli contributed a lot of testing and discovered many bugs. - @CrimsonVoid contributed changes to the bootstrap script.
Diffstat (limited to 'DOCS/waf-buildsystem.rst')
1 files changed, 151 insertions, 0 deletions
diff --git a/DOCS/waf-buildsystem.rst b/DOCS/waf-buildsystem.rst
new file mode 100644
index 0000000000..ca52531501
--- /dev/null
+++ b/DOCS/waf-buildsystem.rst
@@ -0,0 +1,151 @@
+waf build system overview
+mpv's new build system is based on waf and it should completly replace the
+custom ./configure + Makefile based system inherited from MPlayer.
+Goals and the choice of waf
+The new system comes with some goals, which can be summed up as: be as good as
+the old one at what it did well (customizability) and fix some of it's major
+1) The build system must be uniform in how it handles any single feature check.
+ Repetition and boilerplate have to be avoided.
+ When adding a new feature using the old configure, one had to add a fair
+ amount of code to the shell script to do option parsing, detection of the
+ feature and declaration of variables for the Makefile to pickup. The worst
+ part is this pieces are spread apart in the configure and copy pasted for
+ any single case. That brings us to..
+2) --enable-feature has to override the user and help him understand that he
+ has libraries missing and should install them for the feature to be enabled.
+3) Must be customizable, hackable, pleasant to the developer eyes and to work
+ with in general.
+4) Must have separate configuration and build steps.
+Goal 2 comes as a given on pretty much any build system, since autotools made
+this behaviour very popular among users (and rightly so).
+Goal 1+3 were somewhat harder to accomplish as it looks like all of the build
+systems we evaluated (waf included!) had problems with them. For reference we
+had proof of concept build systems with waf, CMake and autotools.
+What puts waf apart from CMake and autotools, is that projects using it use
+Python to program their build system. Also while the Waf Book shows really
+simple API usages, you can write your own build system on top of waf that is
+tailored to the project's specific needs.
+mpv's custom configure step on top of waf
+To some extents mpv has a custom build system written on top of waf. This
+document will not go over the standard waf behaviour as that is documented in
+the ``Waf book``.
+All of the configuration process is handled with a declarative approach. Lists
+of dictionaries define the checks, and some custom Python code traverses these
+lists and depending on the check definition it calls into the actual waf API.
+A simple example using pkg-config would be::
+ {
+ 'name': '--vdpau',
+ 'desc': 'VDPAU acceleration',
+ 'deps': [ 'x11' ],
+ 'func': check_pkg_config('vdpau', '>= 0.2'),
+ }
+This defines a feature called ``vdpau`` which can be enabled or disabled by
+the users with configure flags (that's the meaning of ``--``). This feature
+depends on another feature whose name is ``x11``, and the autodetection check
+consists of running ``pkg-config`` and looking for ``vdpau`` with version
+``>= 0.2``. If the check succeds a ``#define HAVE_VDPAU 1`` will be added to
+``config.h``, if not ``#define HAVE_VDPAU 0`` will be added.
+The defines names are automatically prepended with ``HAVE_``, capitalized and
+special characters are replaced with underscores. This happens in
+Mandatory fields:
+``name``: indicates the unique identifier used by the custom dependency code
+to refer to a feature. If the unique identifier is prepended with ``--``
+the build system will also generate options for ``./waf configure`` so that
+the feature can be enabled and disabled.
+``desc``: this is the textual representation of the feature used in the
+interactions with the users.
+``func``: function that will perform the check. These functions are defined in
+``waftools/checks``. The reusable checks are all functions that return
+functions. The return functions will then be applied using waf's configuration
+The source code for the reusable checks is a bit convoluted, but it should be
+easy to pick up their usage from the ``wscript``. Their signature mirrors
+the semantics of some of the shell functions used in mplayer.
+If someone expresses some interest, I will extend this document with official
+documentation for each check function.
+Optional fields
+``deps``: list of dependencies of this feature. It is a list of names of
+other features as defined in the ``name`` field (minus the eventual leading
+``--``). All of the dependencies must be satisfied. If they are not the check
+will be skipped without even running ``func``.
+``deps_any``: like deps but it is satisfied even if only one of the dependencies
+is satisfied. You can think of ``deps`` as a 'and' condition and ``deps_any``
+as a 'or' condition.
+``deps_neg``: like deps but it is satisfied when none of the dependencies is
+``req``: defaults to False. If set to True makes this feature a hard
+dependency of mpv (configuration will fail if autodetection fails). If set to
+True you must also provide ``fmsg``.
+``fmsg``: string with the failure message in case a required dependency is not
+``os_specific_checks``: this takes a dictionary that has ``os-`` dependencies
+as keys (such as ``os-win32``), and by values has another dictionary that is
+merged on top of the current feature definition only for that specific OS.
+For example::
+ {
+ 'name': '--pthreads',
+ 'desc': 'POSIX threads',
+ 'func': check_pthreads,
+ 'os_specific_checks': {
+ 'os-win32': {
+ 'func': check_pthreads_w32_static.
+ }
+ }
+ }
+will override the value of ``func`` with ``check_pthreads_w32_static`` only
+if the target OS of the build is Windows.
+mpv's custom build step on top of waf
+Build step is pretty much vanilla waf. The only difference being that the list
+of source files can contain both strings or tuples. If a tuple is found,
+the second element in the tuple will the used to match the features detected
+in the configure step (the ``name`` field described above). If this feature
+was not enabled during configure, the source file will not be compiled in.
+All of the custom Python for this is inside the function ``filtered_sources``
+contained in the file ``waftools/``.
+Also ``dependencies_use`` and ``dependencies_includes`` collect cflags and
+ldflags that were generated from the features checks in the configure step.