aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Stefano Pigozzi <stefano.pigozzi@gmail.com>2013-07-16 13:28:28 +0200
committerGravatar Stefano Pigozzi <stefano.pigozzi@gmail.com>2013-11-21 21:22:36 +0100
commit7e2edad8efea55e8df1faa695d1389ef4e326d7c (patch)
treef9662620b8ecaf50f6c67804dd0d99d00d85fe5b
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 README.md 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.
-rw-r--r--.gitignore6
-rw-r--r--.travis.yml5
-rw-r--r--DOCS/crosscompile-mingw.txt6
-rw-r--r--DOCS/man/docutils.conf1
-rw-r--r--DOCS/waf-buildsystem.rst151
-rw-r--r--README.md38
-rwxr-xr-xTOOLS/osxbundle.py20
-rw-r--r--TOOLS/osxbundle/mpv.app/Contents/Info.plist2
-rwxr-xr-xbootstrap.py28
-rwxr-xr-xold-configure (renamed from configure)107
-rw-r--r--old-makefile (renamed from Makefile)5
-rw-r--r--osdep/getch2.c1
-rw-r--r--video/out/x11_common.c6
-rw-r--r--waftools/__init__.py2
-rw-r--r--waftools/checks/__init__.py0
-rw-r--r--waftools/checks/custom.py119
-rw-r--r--waftools/checks/generic.py134
-rw-r--r--waftools/dependencies.py210
-rw-r--r--waftools/detections/__init__.py0
-rw-r--r--waftools/detections/compiler.py57
-rw-r--r--waftools/detections/cpu.py28
-rw-r--r--waftools/detections/devices.py29
-rw-r--r--waftools/features.py69
-rw-r--r--waftools/fragments/cocoa.m11
-rw-r--r--waftools/fragments/coreaudio.c15
-rw-r--r--waftools/fragments/dvb.c10
-rw-r--r--waftools/fragments/ebx.c12
-rw-r--r--waftools/fragments/gl_x11.c9
-rw-r--r--waftools/fragments/iconv.c30
-rw-r--r--waftools/fragments/libavfilter.c7
-rw-r--r--waftools/fragments/lua.c24
-rw-r--r--waftools/fragments/lua_libquvi4.c3
-rw-r--r--waftools/fragments/lua_libquvi9.c3
-rw-r--r--waftools/fragments/mng.c7
-rw-r--r--waftools/fragments/oss_audio.c11
-rw-r--r--waftools/fragments/oss_audio_header.c13
-rw-r--r--waftools/fragments/pthreads.c10
-rw-r--r--waftools/fragments/pvr.c7
-rw-r--r--waftools/fragments/vcd_windows.c7
-rw-r--r--waftools/fragments/wasapi.c19
-rw-r--r--waftools/fragments/xf86vm.c8
-rw-r--r--waftools/fragments/xf86xk.c6
-rw-r--r--waftools/generators/__init__.py0
-rw-r--r--waftools/generators/headers.py36
-rw-r--r--waftools/generators/sources.py37
-rw-r--r--waftools/inflectors.py26
-rw-r--r--waftools/waf_customizations.py46
-rw-r--r--wscript759
-rw-r--r--wscript_build.py459
49 files changed, 2480 insertions, 119 deletions
diff --git a/.gitignore b/.gitignore
index f4361056da..bf482108b7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@
*.a
*.d
*.exe
+*.pyc
.depend
/config.h
@@ -25,3 +26,8 @@
/DOCS/man/*/mpv.out
/DOCS/man/*/mpv.pdf
/DOCS/man/*/mpv.toc
+
+/waf
+/build
+/.waf*
+/.lock-waf_*
diff --git a/.travis.yml b/.travis.yml
index 4e497eea82..5fc66cd2f2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,7 +13,10 @@ branches:
- ci
before_install: ./travis-deps libass-stable $LIBAV
-script: ./configure && make
+script:
+ - ./bootstrap.py
+ - ./waf configure
+ - ./waf build
notifications-policy: &notifications-policy
on_success: change
diff --git a/DOCS/crosscompile-mingw.txt b/DOCS/crosscompile-mingw.txt
index 8ad59c693f..b971dffdc5 100644
--- a/DOCS/crosscompile-mingw.txt
+++ b/DOCS/crosscompile-mingw.txt
@@ -3,7 +3,7 @@ produce both 32 bit and 64 bit executables. MinGW-w64 is available from
http://mingw-w64.sourceforge.net.
You have to run mpv's configure with these arguments:
- ./configure --enable-cross-compile --target=i686-w64-mingw32
+ DEST_OS=win32 TARGET=i686-w64-mingw32 ./waf configure
Using mingw-w64-cmake to setup a MinGW-w64 environment is recommended (this will
also build mpv and its dependencies): https://github.com/lachs0r/mingw-w64-cmake
@@ -44,8 +44,8 @@ make pthreads
git clone https://github.com/mpv-player/mpv.git
cd mpv
export PATH=/opt/mingw/usr/bin/:$PATH
-./configure --enable-cross-compile --target=i686-w64-mingw32
-make
+DEST_OS=win32 TARGET=i686-w64-mingw32 ./waf configure
+./waf build
# This should work. Note however that MXE’s ffmpeg package might be very old
# in order to avoid breaking e.g. xine-lib, so you might want to update that
diff --git a/DOCS/man/docutils.conf b/DOCS/man/docutils.conf
index cd6e3acd52..2e4d0dcf43 100644
--- a/DOCS/man/docutils.conf
+++ b/DOCS/man/docutils.conf
@@ -10,7 +10,6 @@ latex-preamble: \usepackage[usenames,dvipsnames]{xcolor}
\makeatletter
\renewcommand{\maketitle}{
\begin{center}
- \includegraphics{etc/mpv-icon-8bit-64x64.png}\\
\vspace*{-1.5em}
\begin{Huge}
\@title
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
+shortcomings:
+
+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
+``waftools/inflectors.py``.
+
+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
+context.
+
+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
+satisfied.
+
+``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
+satisfied.
+
+``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/dependencies.py``.
+
+Also ``dependencies_use`` and ``dependencies_includes`` collect cflags and
+ldflags that were generated from the features checks in the configure step.
diff --git a/README.md b/README.md
index f1286bea01..2e8c1d75ff 100644
--- a/README.md
+++ b/README.md
@@ -16,12 +16,22 @@ Compilation
-----------
Compiling with full features requires development files for several
-external libraries. Below is a list of some important requirements. For
-more information see the output of `./configure --help` for a list of options,
-or look at the list of enabled and disabled features printed after running
-`./configure`. If you think you have support for some feature installed
-but configure fails to detect it, the file `config.log` may contain
-information about the reasons for the failure.
+external libraries. Below is a list of some important requirements.
+
+The mpv build system uses *waf* but we don't store it in your source tree. The
+script './bootstrap.py' will download the latest version of waf that was tested
+with the build system.
+
+For a list of the available build options use `./waf configure --help`. If
+you think you have support for some feature installed but configure fails to
+detect it, the file `build/config.log` may contain information about the
+reasons for the failure.
+
+To build the software you can use `./waf build`, and `./waf install` to install
+it.
+
+NOTE: Using the old build system (with `./old-configure`) should still work,
+but will be removed in a future version of mpv.
Essential dependencies (incomplete list):
@@ -47,22 +57,6 @@ If you are running Mac OSX and using homebrew we provide [homebrew-mpv][homebrew
to date formula that compiles mpv with sensible dependencies and defaults for
OSX.
-### configure `--enable-*` parameters
-
-The `--enable-*` parameters unconditionally force options on, completely
-skipping autodetection. This behavior is unlike what you may be used to from
-autoconf-based configure scripts that can decide to override you. This greater
-level of control comes at a price. You may have to provide the correct compiler
-and linker flags yourself.
-
-If you used one of these options and experience a compilation or
-linking failure, make sure you have passed the necessary compiler/linker flags
-to configure.
-
-mpv's configure script is greedy and automatically enables features as a result
-of autodetection. The cases where you may want to use `--enable-*` are very
-limited.
-
FFmpeg vs. Libav
----------------
diff --git a/TOOLS/osxbundle.py b/TOOLS/osxbundle.py
index 6cd2a227c5..66ef576efd 100755
--- a/TOOLS/osxbundle.py
+++ b/TOOLS/osxbundle.py
@@ -30,24 +30,28 @@ def user_dylib_lst(input_file):
return [lib for lib in dylib_lst(input_file).split("\n") if
is_user_lib(lib, input_file)]
-def bundle_name(binary_name):
+def bundle_path(binary_name):
return "%s.app" % binary_name
+def bundle_name(binary_name):
+ return os.path.basename(bundle_path(binary_name))
+
def target_plist(binary_name):
- return os.path.join(bundle_name(binary_name), 'Contents', 'Info.plist')
+ return os.path.join(bundle_path(binary_name), 'Contents', 'Info.plist')
def target_directory(binary_name):
- return os.path.join(bundle_name(binary_name), 'Contents', 'MacOS')
+ return os.path.join(bundle_path(binary_name), 'Contents', 'MacOS')
def target_binary(binary_name):
- return os.path.join(target_directory(binary_name), binary_name)
+ return os.path.join(target_directory(binary_name),
+ os.path.basename(binary_name))
def copy_bundle(binary_name):
- if os.path.isdir(bundle_name(binary_name)):
- shutil.rmtree(bundle_name(binary_name))
+ if os.path.isdir(bundle_path(binary_name)):
+ shutil.rmtree(bundle_path(binary_name))
shutil.copytree(
os.path.join('TOOLS', 'osxbundle', bundle_name(binary_name)),
- bundle_name(binary_name))
+ bundle_path(binary_name))
def copy_binary(binary_name):
shutil.copy(binary_name, target_binary(binary_name))
@@ -91,7 +95,7 @@ def fix_dylibs_paths(target_file, dest_dir, root=True):
fix_dylibs_paths(dylib_dest_path, dest_dir, False)
def apply_plist_template(plist_file, version):
- sh("sed -i -e 's/{{VERSION}}/%s/g' %s" % (version, plist_file))
+ sh("sed -i -e 's/${VERSION}/%s/g' %s" % (version, plist_file))
def bundle_dependencies(binary_name):
lib_bundle_directory = os.path.join(target_directory(binary_name), "lib")
diff --git a/TOOLS/osxbundle/mpv.app/Contents/Info.plist b/TOOLS/osxbundle/mpv.app/Contents/Info.plist
index f1e2e6f34d..0573b62e44 100644
--- a/TOOLS/osxbundle/mpv.app/Contents/Info.plist
+++ b/TOOLS/osxbundle/mpv.app/Contents/Info.plist
@@ -183,7 +183,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
- <string>{{VERSION}}</string>
+ <string>${VERSION}</string>
<key>NSHighResolutionCapable</key>
<true/>
<key>CFBundleURLTypes</key>
diff --git a/bootstrap.py b/bootstrap.py
new file mode 100755
index 0000000000..d855de029b
--- /dev/null
+++ b/bootstrap.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+
+# This script simply downloads waf to the current directory
+
+from __future__ import print_function
+import os, sys, stat, hashlib
+
+try:
+ from urllib.request import urlopen
+except:
+ from urllib2 import urlopen
+
+WAFRELEASE = "waf-1.7.13"
+SHA256HASH = "03cc750049350ee01cdbc584b70924e333fcc17ba4a2d04648dab1535538a873"
+
+waf = urlopen("https://waf.googlecode.com/files/" + WAFRELEASE).read()
+
+if SHA256HASH == hashlib.sha256(waf).hexdigest():
+ with open("waf", "wb") as wf:
+ wf.write(waf)
+
+ os.chmod("waf", os.stat("waf").st_mode | stat.S_IXUSR)
+ print("Checksum verified.")
+else:
+ print("The checksum of the downloaded file does not match!")
+ print("Please download and verify the file manually.")
+
+ sys.exit(1)
diff --git a/configure b/old-configure
index 0618c05594..fe77403c6b 100755
--- a/configure
+++ b/old-configure
@@ -1722,56 +1722,10 @@ fi
echores "$_wayland"
unset _wlver
-echocheck "X11 headers presence"
- _x11_headers="no"
- res_comment="check if the dev(el) packages are installed"
- for I in $(echo $extra_cflags | sed s/-I//g) /usr/include ; do
- if test -f "$I/X11/Xlib.h" ; then
- _x11_headers="yes"
- res_comment=""
- break
- fi
- done
- if test $_cross_compile = no; then
- for I in /usr/X11/include /usr/X11R7/include /usr/local/include /usr/X11R6/include \
- /usr/include/X11R6 /usr/openwin/include ; do
- if test -f "$I/X11/Xlib.h" ; then
- extra_cflags="$extra_cflags -I$I"
- _x11_headers="yes"
- res_comment="using $I"
- break
- fi
- done
- fi
-echores "$_x11_headers"
-
-
echocheck "X11"
-if test "$_x11" = auto && test "$_x11_headers" = yes ; then
- for I in "" -L/usr/X11R7/lib -L/usr/local/lib -L/usr/X11R6/lib -L/usr/lib/X11R6 \
- -L/usr/X11/lib -L/usr/lib32 -L/usr/openwin/lib -L/usr/local/lib64 -L/usr/X11R6/lib64 \
- -L/usr/lib ; do
- if netbsd; then
- _ld_tmp="$I -lXext -lX11 $_ld_pthread -Wl,-R$(echo $I | sed s/^-L//)"
- else
- _ld_tmp="$I -lXext -lX11 $_ld_pthread"
- fi
- statement_check_broken X11/Xutil.h X11/XKBlib.h 'XCreateWindow(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)' $_ld_tmp &&
- _x11=yes
- # Check that there aren't conflicting headers between ApplicationServices
- # and X11. On versions of Mac OSX prior to 10.7 the deprecated QuickDraw API
- # is included by -framework ApplicationServices and clashes with the X11
- # definition of the "Cursor" type.
- if darwin && depends_on_application_services && test "$_x11" = yes ; then
- _x11=no
- header_check_broken ApplicationServices/ApplicationServices.h \
- X11/Xutil.h $_ld_tmp && _x11=yes
- fi
- if test "$_x11" = yes ; then
- libs_mplayer="$libs_mplayer $_ld_tmp"
- break
- fi
- done
+if test "$_x11" = auto ; then
+ _x11="no"
+ pkg_config_add "x11" && _x11="yes"
fi
if test "$_x11" = yes ; then
def_x11='#define HAVE_X11 1'
@@ -1797,36 +1751,19 @@ else
fi
echores "$_xss"
-echocheck "DPMS"
-_xdpms3=no
-_xdpms4=no
+echocheck "X extensions"
+_xext=no
if test "$_x11" = yes ; then
- cat > $TMPC <<EOF
-#include <X11/Xmd.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xatom.h>
-#include <X11/extensions/dpms.h>
-int main(void) { DPMSQueryExtension(0, 0, 0); return 0; }
-EOF
- cc_check -lXdpms && _xdpms3=yes
- statement_check_broken X11/Xlib.h X11/extensions/dpms.h 'DPMSQueryExtension(0, 0, 0)' -lXext && _xdpms4=yes
+ pkg_config_add "xext" && _xext="yes"
fi
-if test "$_xdpms4" = yes ; then
- def_xdpms='#define HAVE_XDPMS 1'
- res_comment="using Xdpms 4"
- echores "yes"
-elif test "$_xdpms3" = yes ; then
- def_xdpms='#define HAVE_XDPMS 1'
- libs_mplayer="$libs_mplayer -lXdpms"
- res_comment="using Xdpms 3"
+if test "$_xext" = yes ; then
+ def_xext='#define HAVE_XEXT 1'
echores "yes"
else
- def_xdpms='#define HAVE_XDPMS 0'
+ def_xext='#define HAVE_XEXT 0'
echores "no"
fi
-
echocheck "Xv"
if test "$_xv" = auto && test "$_x11" = yes ; then
_xv=no
@@ -3232,10 +3169,22 @@ CXXFLAGS=" $CFLAGS -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMI
# DO NOT ADD ANY TESTS THAT USE LINKER FLAGS HERE (like cc_check).
+# This is done so waf builds won't conflict with this. In fact, waf and old
+# build system can coexist in parallel, at the same time. This is because
+# waf always does out-of-tree builds, while this build system does always
+# in-tree builds.
+
+if test ! -f Makefile ; then
+ ln -s old-makefile Makefile
+fi
+rm -rf old_build
+mkdir old_build
+
+BUILDCFLAGS="-Iold_build"
#############################################################################
echo "Creating config.mak"
-cat > config.mak << EOF
+cat > old_build/config.mak << EOF
# -------- Generated by configure -----------
# Ensure that locale settings do not interfere with shell commands.
@@ -3254,8 +3203,8 @@ CXX = $_cc
INSTALL = $_install
WINDRES = $_windres
-CFLAGS = $WARNFLAGS $ERRORFLAGS $WARN_CFLAGS $CFLAGS $extra_cflags
-CXXFLAGS = $WARNFLAGS $ERRORFLAGS $CXXFLAGS $extra_cflags $extra_cxxflags
+CFLAGS = $BUILDCFLAGS $WARNFLAGS $ERRORFLAGS $WARN_CFLAGS $CFLAGS $extra_cflags
+CXXFLAGS = $BUILDCFLAGS $WARNFLAGS $ERRORFLAGS $CXXFLAGS $extra_cflags $extra_cxxflags
DEPFLAGS = $DEPFLAGS
EXTRALIBS = $extra_ldflags $_ld_static $_ld_lm $extra_libs $libs_mplayer $end_ldflags
@@ -3530,7 +3479,7 @@ $def_vaapi_hwaccel
$def_vm
$def_x11
$def_wayland
-$def_xdpms
+$def_xext
$def_xf86keysym
$def_xinerama
$def_xss
@@ -3555,7 +3504,7 @@ $def_pthreads
EOF
# Do not overwrite an unchanged config.h to avoid superfluous rebuilds.
-cmp -s "$TMPH" config.h || mv -f "$TMPH" config.h
+cmp -s "$TMPH" old_build/config.h || mv -f "$TMPH" old_build/config.h
#############################################################################
@@ -3601,6 +3550,10 @@ If you used one of these options and experience a compilation or
linking failure, make sure you have passed the necessary compiler/linker flags
to configure.
+WARNING: The ./old-configure + make build system you are using is deprecated in
+favour of waf and will be removed in a future version of mpv. Check the
+README for instructions on how to build mpv with the new build system.
+
EOF
if test "$warn_cflags" = yes; then
diff --git a/Makefile b/old-makefile
index 9323b2e72a..a6902fbb1a 100644
--- a/Makefile
+++ b/old-makefile
@@ -19,7 +19,7 @@
# with MPlayer; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-include config.mak
+include old_build/config.mak
###### variable declarations #######
@@ -535,7 +535,8 @@ clean:
-$(RM) mpvcore/player/lua/osc.inc
distclean: clean
- -$(RM) config.log config.mak config.h TAGS tags
+ -$(RM) config.log old_build/config.h old_build/config.mak Makefile config.mak config.h TAGS tags
+ -rmdir old_build/
TAGS:
$(RM) $@; find . -name '*.[chS]' -o -name '*.asm' | xargs etags -a
diff --git a/osdep/getch2.c b/osdep/getch2.c
index ccfef64ac0..b189a678db 100644
--- a/osdep/getch2.c
+++ b/osdep/getch2.c
@@ -73,7 +73,6 @@ static keycode_map getch2_keys;
#if HAVE_TERMINFO || HAVE_TERMCAP
-
static char *term_rmkx = NULL;
static char *term_smkx = NULL;
diff --git a/video/out/x11_common.c b/video/out/x11_common.c
index 09492a2294..54cd063505 100644
--- a/video/out/x11_common.c
+++ b/video/out/x11_common.c
@@ -50,7 +50,7 @@
#include <X11/extensions/scrnsaver.h>
#endif
-#if HAVE_XDPMS
+#if HAVE_XEXT
#include <X11/extensions/dpms.h>
#endif
@@ -1552,7 +1552,7 @@ static void saver_on(struct vo_x11_state *x11)
x11->screensaver_off = 0;
if (xss_suspend(mDisplay, False))
return;
-#if HAVE_XDPMS
+#if HAVE_XEXT
if (x11->dpms_disabled) {
int nothing;
if (DPMSQueryExtension(mDisplay, &nothing, &nothing)) {
@@ -1587,7 +1587,7 @@ static void saver_off(struct vo_x11_state *x11)
x11->screensaver_off = 1;
if (xss_suspend(mDisplay, True))
return;
-#if HAVE_XDPMS
+#if HAVE_XEXT
if (DPMSQueryExtension(mDisplay, &nothing, &nothing)) {
BOOL onoff;
CARD16 state;
diff --git a/waftools/__init__.py b/waftools/__init__.py
new file mode 100644
index 0000000000..6f804bce35
--- /dev/null
+++ b/waftools/__init__.py
@@ -0,0 +1,2 @@
+#!/usr/bin/env python
+# encoding: utf-8
diff --git a/waftools/checks/__init__.py b/waftools/checks/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/waftools/checks/__init__.py
diff --git a/waftools/checks/custom.py b/waftools/checks/custom.py
new file mode 100644
index 0000000000..d2da024037
--- /dev/null
+++ b/waftools/checks/custom.py
@@ -0,0 +1,119 @@
+from waftools.checks.generic import *
+
+__all__ = ["check_pthreads", "check_iconv", "check_lua", "check_oss"]
+
+pthreads_program = load_fragment('pthreads.c')
+
+def check_pthreads(ctx, dependency_identifier):
+ platform_cflags = {
+ 'linux': '-D_REENTRANT',
+ 'freebsd': '-D_THREAD_SAFE',
+ 'netbsd': '-D_THREAD_SAFE',
+ 'openbsd': '-D_THREAD_SAFE',
+ 'win32': '-DPTW32_STATIC_LIB',
+ }.get(ctx.env.DEST_OS, '')
+ libs = ['pthreadGC2', 'pthread']
+ checkfn = check_cc(fragment=pthreads_program, cflags=platform_cflags)
+ return check_libs(libs, checkfn)(ctx, dependency_identifier)
+
+def check_iconv(ctx, dependency_identifier):
+ iconv_program = load_fragment('iconv.c')
+ libdliconv = " ".join(ctx.env.LIB_LIBDL + ['iconv'])
+ libs = ['iconv', libdliconv]
+ checkfn = check_cc(fragment=iconv_program)
+ return check_libs(libs, checkfn)(ctx, dependency_identifier)
+
+def check_lua(ctx, dependency_identifier):
+ if 'libquvi4' in ctx.env.satisfied_deps:
+ additional_lua_test_header = '#include <quvi/quvi.h>'
+ additional_lua_test_code = load_fragment('lua_libquvi4.c')
+ elif 'libquvi9' in ctx.env.satisfied_deps:
+ additional_lua_test_header = '#include <quvi.h>'
+ additional_lua_test_code = load_fragment('lua_libquvi9.c')
+ else:
+ additional_lua_test_header = ''
+ additional_lua_test_code = ''
+
+ fragment = load_fragment('lua.c').format(
+ additional_lua_test_header='',
+ additional_lua_test_code='')
+
+ lua_versions = [
+ ( '51', 'lua >= 5.1.0 lua < 5.2.0'),
+ ( '51deb', 'lua5.1 >= 5.1.0'), # debian
+ ( 'luajit', 'luajit >= 2.0.0' ),
+ # assume all our dependencies (libquvi in particular) link with 5.1
+ ( '52', 'lua >= 5.2.0' ),
+ ( '52deb', 'lua5.2 >= 5.2.0'), # debian
+ ]
+
+ if ctx.options.LUA_VER:
+ lua_versions = \
+ [lv for lv in lua_versions if lv[0] == ctx.options.LUA_VER]
+
+ for lua_version, pkgconfig_query in lua_versions:
+ if compose_checks(
+ check_pkg_config(pkgconfig_query, uselib_store=lua_version),
+ check_cc(fragment=fragment, use=lua_version))\
+ (ctx, dependency_identifier):
+ # XXX: this is a bit of a hack, ask waf developers if I can copy
+ # the uselib_store to 'lua'
+ ctx.mark_satisfied(lua_version)
+ ctx.add_optional_message(dependency_identifier,
+ 'version found: ' + lua_version)
+ return True
+ return False
+
+# from here on there is the OSS check.. just stop reading here unless you want
+# to die inside a little
+def __fail_oss_check__(ctx):
+ ctx.define('PATH_DEV_DSP', '')
+ ctx.define('PATH_DEV_MIXER', '')
+ return False
+
+def __get_osslibdir__():
+ try:
+ cmd = ['sh', '-c', "'source /etc/oss.conf && echo $OSSLIBDIR'"]
+ p = Utils.subprocess.Popen(cmd, stdin=Utils.subprocess.PIPE,
+ stdout=Utils.subprocess.PIPE,
+ stderr=Utils.subprocess.PIPE)
+ return p.communicate()[0]
+ except Exception:
+ return ""
+
+def __check_oss_headers__(ctx, dependency_identifier):
+ import os
+
+ real_oss = ctx.check_cc(fragment=load_fragment('oss_audio_header.c'),
+ use='soundcard')
+
+ if real_oss:
+ if os.path.exists('/etc/oss.conf'):
+ osslibdir = __get_osslibdir__()
+ ossincdir = os.path.join(osslibdir, 'include')
+ soundcard_h = os.path.join(ossincdir, 'sys', 'soundcard.h')
+ if os.path.exists(soundcard_h):
+ ctx.env.CFLAGS.append('-I{0}'.format(ossincdir))
+
+ return True
+
+def __check_oss_bsd__(ctxdependency_identifier):
+ # add the oss audio library through a check
+ ctx.define('PATH_DEV_DSP', '/dev/sound')
+ if check_cc(lib='ossaudio')(ctx, dependency_identifier):
+ return True
+ else:
+ return __fail_oss_check__(ctx)
+
+def check_oss(ctx, dependency_identifier):
+ func = check_cc(fragment=load_fragment('oss_audio.c'), use='soundcard')
+ if func(ctx, dependency_identifier):
+ ctx.define('PATH_DEV_DSP', '/dev/dsp')
+ ctx.define('PATH_DEV_MIXER', '/dev/mixer')
+
+ if ctx.env.DEST_OS in ['openbsd', 'netbsd']:
+ return __check_oss_bsd_library__(ctx, dependency_identifier)
+ else:
+ return __check_oss_headers__(ctx, dependency_identifier)
+
+ return __fail_oss_check__(ctx)
diff --git a/waftools/checks/generic.py b/waftools/checks/generic.py
new file mode 100644
index 0000000000..46813aed01
--- /dev/null
+++ b/waftools/checks/generic.py
@@ -0,0 +1,134 @@
+import os
+from inflectors import DependencyInflector
+
+__all__ = [
+ "check_pkg_config", "check_cc", "check_statement", "check_libs",
+ "check_headers", "compose_checks", "check_true", "any_version",
+ "load_fragment", "check_stub", "check_ctx_vars"]
+
+any_version = None
+
+def even(n):
+ return n % 2 == 0
+
+def __define_options__(dependency_identifier):
+ return DependencyInflector(dependency_identifier).define_dict()
+
+def __merge_options__(dependency_identifier, *args):
+ options_accu = DependencyInflector(dependency_identifier).storage_dict()
+ options_accu['mandatory'] = False
+ [options_accu.update(arg) for arg in args if arg]
+ return options_accu
+
+
+def check_libs(libs, function):
+ libs = [None] + libs
+ def fn(ctx, dependency_identifier):
+ for lib in libs:
+ kwargs = lib and {'lib': lib} or {}
+ if function(ctx, dependency_identifier, **kwargs):
+ return True
+ return False
+ return fn
+
+def check_statement(header, statement, **kw_ext):
+ def fn(ctx, dependency_identifier, **kw):
+ fragment = """
+ #include <{0}>
+ int main(int argc, char **argv)
+ {{ {1}; return 0; }} """.format(header, statement)
+ opts = __merge_options__(dependency_identifier,
+ {'fragment':fragment},
+ __define_options__(dependency_identifier),
+ kw_ext, kw)
+ return ctx.check_cc(**opts)
+ return fn
+
+def check_cc(**kw_ext):
+ def fn(ctx, dependency_identifier, **kw):
+ options = __merge_options__(dependency_identifier,
+ __define_options__(dependency_identifier),
+ kw_ext, kw)
+ return ctx.check_cc(**options)
+ return fn
+
+def check_pkg_config(*args, **kw_ext):
+ def fn(ctx, dependency_identifier, **kw):
+ argsl = list(args)
+ packages = [el for (i, el) in enumerate(args) if even(i)]
+ sargs = [i for i in args if i] # remove None
+ pkgc_args = ["--libs", "--cflags"]
+ if ctx.dependency_satisfied('static-build'):
+ pkgc_args += ["--static"]
+
+ defaults = {
+ 'path': ctx.env.PKG_CONFIG,
+ 'package': " ".join(packages),
+ 'args': sargs + pkgc_args }
+ opts = __merge_options__(dependency_identifier, defaults, kw_ext, kw)
+ if ctx.check_cfg(**opts):
+ return True
+ else:
+ defkey = DependencyInflector(dependency_identifier).define_key()
+ ctx.undefine(defkey)
+ return False
+ return fn
+
+def check_headers(*headers):
+ def undef_others(ctx, headers, found):
+ not_found_hs = set(headers) - set([found])
+ for not_found_h in not_found_hs:
+ defkey = DependencyInflector(not_found_h).define_key()
+ ctx.undefine(defkey)
+
+ def fn(ctx, dependency_identifier):
+ for header in headers:
+ defaults = {'header_name': header, 'features': 'c cprogram'}
+ options = __merge_options__(dependency_identifier, defaults)
+ if ctx.check(**options):
+ undef_others(ctx, headers, header)
+ defkey = DependencyInflector(dependency_identifier).define_key()
+ ctx.define(defkey, 1)
+ return True
+ undef_others(ctx, headers, None)
+ return False
+ return fn
+
+def check_true(ctx, dependency_identifier):
+ defkey = DependencyInflector(dependency_identifier).define_key()
+ ctx.define(defkey, 1)
+ return True
+
+def check_ctx_vars(*variables):
+ def fn(ctx, dependency_identifier):
+ missing = []
+ for variable in variables:
+ if variable not in ctx.env:
+ missing.append(variable)
+
+ if any(missing):
+ ctx.add_optional_message(dependency_identifier,
+ 'missing {0}'.format(', '.join(missing)))
+ return False
+ else:
+ return True
+
+ return fn
+
+def check_stub(ctx, dependency_identifier):
+ defkey = DependencyInflector(dependency_identifier).define_key()
+ ctx.undefine(defkey)
+ return False
+
+def compose_checks(*checks):
+ def fn(ctx, dependency_identifier):
+ return all([check(ctx, dependency_identifier) for check in checks])
+ return fn
+
+def load_fragment(fragment):
+ file_path = os.path.join(os.path.dirname(__file__), '..', 'fragments',
+ fragment)
+ fp = open(file_path,"r")
+ fragment_code = fp.read()
+ fp.close()
+ return fragment_code
diff --git a/waftools/dependencies.py b/waftools/dependencies.py
new file mode 100644
index 0000000000..cd85180fae
--- /dev/null
+++ b/waftools/dependencies.py
@@ -0,0 +1,210 @@
+from waflib.Errors import ConfigurationError, WafError
+from waflib.Configure import conf
+from waflib.Build import BuildContext
+from waflib.Logs import pprint
+from inflectors import DependencyInflector
+
+class DependencyError(Exception):
+ pass
+
+class Dependency(object):
+ def __init__(self, ctx, known_deps, satisfied_deps, dependency):
+ self.ctx = ctx
+ self.known_deps = known_deps
+ self.satisfied_deps = satisfied_deps
+ self.identifier, self.desc = dependency['name'], dependency['desc']
+ self.attributes = self.__parse_attributes__(dependency)
+
+ ctx.env.known_deps.add(self.identifier)
+ for dep_key in ['deps', 'deps_any', 'deps_neg']:
+ if dep_key in self.attributes:
+ deps = self.attributes[dep_key]
+ self.ctx.ensure_dependency_is_known(*deps)
+
+
+ def __parse_attributes__(self, dependency):
+ if 'os_specific_checks' in dependency:
+ all_chks = dependency['os_specific_checks']
+ chks = [check for check in all_chks if check in self.satisfied_deps]
+ if any(chks):
+ return all_chks[chks[0]]
+ return dependency
+
+ def check(self):
+ self.ctx.start_msg('Checking for {0}'.format(self.desc))
+
+ try:
+ self.check_disabled()
+ self.check_any_dependencies()
+ self.check_dependencies()
+ self.check_negative_dependencies()
+ except DependencyError:
+ # No check was run, since the prerequisites of the dependency are
+ # not satisfied. Make sure the define is 'undefined' so that we
+ # get a `#define YYY 0` in `config.h`.
+ def_key = DependencyInflector(self.identifier).define_key()
+ self.ctx.undefine(def_key)
+ self.fatal_if_needed()
+ return
+
+ self.check_autodetect_func()
+
+ def check_disabled(self):
+ if self.enabled_option() == False:
+ self.skip()
+ raise DependencyError
+
+ if self.enabled_option() == True:
+ self.attributes['req'] = True
+ self.attributes['fmsg'] = "You manually enabled the feature '{0}', but \
+the autodetection check failed.".format(self.identifier)
+
+ def check_any_dependencies(self):
+ if 'deps_any' in self.attributes:
+ deps = set(self.attributes['deps_any'])
+ if len(deps & self.satisfied_deps) == 0:
+ self.skip("not found any of {0}".format(", ".join(deps)))
+ raise DependencyError
+
+ def check_dependencies(self):
+ if 'deps' in self.attributes:
+ deps = set(self.attributes['deps'])
+ if not deps <= self.satisfied_deps:
+ missing_deps = deps - self.satisfied_deps
+ self.skip("{0} not found".format(", ".join(missing_deps)))
+ raise DependencyError
+
+ def check_negative_dependencies(self):
+ if 'deps_neg' in self.attributes:
+ deps = set(self.attributes['deps_neg'])
+ if deps <= self.satisfied_deps:
+ conflicting_deps = deps & self.satisfied_deps
+ self.skip("{0} found".format(", ".join(conflicting_deps)), 'CYAN')
+ raise DependencyError
+
+ def check_autodetect_func(self):
+ if self.attributes['func'](self.ctx, self.identifier):
+ self.success(self.identifier)
+ else:
+ self.fail()
+ self.fatal_if_needed()
+
+ def enabled_option(self):
+ try:
+ return getattr(self.ctx.options, self.enabled_option_repr())
+ except AttributeError:
+ pass
+ return None
+
+ def enabled_option_repr(self):
+ return "enable_{0}".format(self.identifier)
+
+ def success(self, depname):
+ self.ctx.mark_satisfied(depname)
+ self.ctx.end_msg(self.__message__('yes'))
+
+ def fail(self, reason='no'):
+ self.ctx.end_msg(self.__message__(reason), 'RED')
+
+ def fatal_if_needed(self):
+ if self.enabled_option() == False:
+ return
+ if self.attributes.get('req', False):
+ raise ConfigurationError(self.attributes['fmsg'])
+
+ def skip(self, reason='disabled', color='YELLOW'):
+ self.ctx.end_msg(self.__message__(reason), color)
+
+ def __message__(self, message):
+ optional_message = self.ctx.deps_msg.get(self.identifier)
+ if optional_message:
+ return "{0} ({1})".format(message, optional_message)
+ else:
+ return message
+
+def configure(ctx):
+ def __detect_target_os_dependency__(ctx):
+ target = "os-{0}".format(ctx.env.DEST_OS)
+ ctx.start_msg('Detected target OS:')
+ ctx.end_msg(target)
+ ctx.env.known_deps.add(target)
+ ctx.env.satisfied_deps.add(target)
+
+ ctx.deps_msg = {}
+ ctx.env['known_deps'] = set()
+ ctx.env['satisfied_deps'] = set()
+ __detect_target_os_dependency__(ctx)
+
+@conf
+def ensure_dependency_is_known(ctx, *depnames):
+ deps = set([d for d in depnames if not d.startswith('os-')])
+ if not deps <= ctx.env.known_deps:
+ raise ConfigurationError(
+ "error in dependencies definition: some dependencies in"
+ " {0} are unknown.".format(deps))
+
+
+@conf
+def mark_satisfied(ctx, dependency_identifier):
+ ctx.env.satisfied_deps.add(dependency_identifier)
+
+@conf
+def add_optional_message(ctx, dependency_identifier, message):
+ ctx.deps_msg[dependency_identifier] = message
+
+@conf
+def parse_dependencies(ctx, dependencies):
+ def __check_dependency__(ctx, dependency):
+ Dependency(ctx,
+ ctx.env.known_deps,
+ ctx.env.satisfied_deps,
+ dependency).check()
+
+ [__check_dependency__(ctx, dependency) for dependency in dependencies]
+
+@conf
+def dependency_satisfied(ctx, dependency_identifier):
+ ctx.ensure_dependency_is_known(dependency_identifier)
+ return dependency_identifier in ctx.env.satisfied_deps
+
+def filtered_sources(ctx, sources):
+ def __source_file__(source):
+ if isinstance(source, tuple):
+ return source[0]
+ else:
+ return source
+
+ def __check_filter__(dependency):
+ if dependency.find('!') == 0:
+ dependency = dependency.lstrip('!')
+ ctx.ensure_dependency_is_known(dependency)
+ return dependency not in ctx.env.satisfied_deps
+ else:
+ ctx.ensure_dependency_is_known(dependency)
+ return dependency in ctx.env.satisfied_deps
+
+ def __unpack_and_check_filter__(source):
+ try:
+ _, dependency = source
+ return __check_filter__(dependency)
+ except ValueError:
+ return True
+
+ return [__source_file__(source) for source in sources \
+ if __unpack_and_check_filter__(source)]
+
+def env_fetch(tx):
+ def fn(ctx):
+ deps = list(ctx.env.satisfied_deps)
+ lists = [ctx.env[tx(dep)] for dep in deps if (tx(dep) in ctx.env)]
+ return [item for sublist in lists for item in sublist]
+ return fn
+
+def dependencies_use(ctx):
+ return [DependencyInflector(dep).storage_key() for \
+ dep in ctx.env.satisfied_deps]
+
+BuildContext.filtered_sources = filtered_sources
+BuildContext.dependencies_use = dependencies_use
+BuildContext.dependencies_includes = env_fetch(lambda x: "INCLUDES_{0}".format(x))
+BuildContext.dependency_satisfied = dependency_satisfied
diff --git a/waftools/detections/__init__.py b/waftools/detections/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/waftools/detections/__init__.py
diff --git a/waftools/detections/compiler.py b/waftools/detections/compiler.py
new file mode 100644
index 0000000000..1fee446409
--- /dev/null
+++ b/waftools/detections/compiler.py
@@ -0,0 +1,57 @@
+from waflib import Utils
+
+def __get_cc_env_vars__(cc):
+ cmd = cc + ['-dM', '-E', '-']
+ try:
+ p = Utils.subprocess.Popen(cmd, stdin=Utils.subprocess.PIPE,
+ stdout=Utils.subprocess.PIPE,
+ stderr=Utils.subprocess.PIPE)
+ p.stdin.write('\n'.encode())
+ return p.communicate()[0]
+ except Exception:
+ return ""
+
+def __add_generic_flags__(ctx):
+ ctx.env.CFLAGS += ["-D_ISOC99_SOURCE", "-D_GNU_SOURCE",
+ "-D_LARGEFILE_SOURCE", "-D_FILE_OFFSET_BITS=64",
+ "-D_LARGEFILE64_SOURCE",
+ "-std=gnu99", "-Wall"]
+
+ if ctx.is_debug_build():
+ ctx.env.CFLAGS += ['-g']
+
+def __add_gcc_flags__(ctx):
+ ctx.env.CFLAGS += ["-Wundef", "-Wmissing-prototypes",
+ "-Wno-switch", "-Wno-parentheses", "-Wpointer-arith",
+ "-Wredundant-decls", "-Wno-pointer-sign",
+ "-Werror=implicit-function-declaration",
+ "-Wno-error=deprecated-declarations",
+ "-Wno-error=unused-function" ]
+
+def __add_clang_flags__(ctx):
+ ctx.env.CFLAGS += ["-Wno-logical-op-parentheses", "-fcolor-diagnostics"]
+
+def __add_mingw_flags__(ctx):
+ ctx.env.CFLAGS += ['-D__USE_MINGW_ANSI_STDIO=1']
+ ctx.env.CFLAGS += ['-DBYTE_ORDER=1234']
+ ctx.env.CFLAGS += ['-DLITLE_ENDIAN=1234']
+ ctx.env.CFLAGS += ['-DBIG_ENDIAN=4321']
+ ctx.env.LAST_LINKFLAGS += ['-mconsole']
+
+__compiler_map__ = {
+ '__GNUC__': __add_gcc_flags__,
+ '__clang__': __add_clang_flags__,
+ '__MINGW32__': __add_mingw_flags__,
+}
+
+def __apply_map__(ctx, fnmap):
+ if 'CC_ENV_VARS' not in ctx.env:
+ ctx.env.CC_ENV_VARS = str(__get_cc_env_vars__(ctx.env.CC))
+ for k, fn in fnmap.items():
+ if ctx.env.CC_ENV_VARS.find(k) > 0:
+ fn(ctx)
+
+def configure(ctx):
+ __add_generic_flags__(ctx)
+ __apply_map__(ctx, __compiler_map__)
+
diff --git a/waftools/detections/cpu.py b/waftools/detections/cpu.py
new file mode 100644
index 0000000000..ce342fdd73
--- /dev/null
+++ b/waftools/detections/cpu.py
@@ -0,0 +1,28 @@
+def x86(ctx):
+ ctx.define('ARCH_X86', 1)
+ ctx.define('ARCH_X86_32', 1)
+
+def x86_64(ctx):
+ ctx.define('ARCH_X86', 1)
+ ctx.define('ARCH_X86_64', 1)
+ ctx.define('HAVE_FAST_64BIT', 1)
+
+def ia64(ctx):
+ ctx.define('HAVE_FAST_64BIT', 1)
+
+def default(ctx):
+ pass
+
+def configure(ctx):
+ ctx.define('ARCH_X86', 0)
+ ctx.define('ARCH_X86_32', 0)
+ ctx.define('ARCH_X86_64', 0)
+ ctx.define('HAVE_FAST_64BIT', 0)
+
+ ctx.define('HAVE_MMX', 'ARCH_X86', quote=False)
+ ctx.define('HAVE_MMX2', 'ARCH_X86', quote=False)
+ ctx.define('HAVE_SSE', 'ARCH_X86', quote=False)
+ ctx.define('HAVE_SSE2', 'ARCH_X86', quote=False)
+ ctx.define('HAVE_SSSE3', 'ARCH_X86', quote=False)
+
+ globals().get(ctx.env.DEST_CPU, default)(ctx)
diff --git a/waftools/detections/devices.py b/waftools/detections/devices.py
new file mode 100644
index 0000000000..2533788691
--- /dev/null
+++ b/waftools/detections/devices.py
@@ -0,0 +1,29 @@
+__cdrom_devices_map__ = {
+ 'win32': 'D:',
+ 'cygwin': 'D:',
+ 'darwin': '/dev/disk1',
+ 'freebsd': '/dev/cd0',
+ 'openbsd': '/dev/rcd0r',
+ 'default': '/dev/cdrom'
+}
+
+__dvd_devices_map__ = {
+ 'win32': 'D:',
+ 'cygwin': 'D:',
+ 'darwin': '/dev/rdiskN',
+ 'freebsd': '/dev/cd0',
+ 'openbsd': '/dev/rcd0r',
+ 'default': '/dev/dvd'
+}
+
+def __default_cdrom_device__(ctx):
+ default = __cdrom_devices_map__['default']
+ return __cdrom_devices_map__.get(ctx.env.DEST_OS, default)
+
+def __default_dvd_device__(ctx):
+ default = __dvd_devices_map__['default']
+ return __dvd_devices_map__.get(ctx.env.DEST_OS, default)
+
+def configure(ctx):
+ ctx.define('DEFAULT_DVD_DEVICE', __default_dvd_device__(ctx))
+ ctx.define('DEFAULT_CDROM_DEVICE', __default_cdrom_device__(ctx))
diff --git a/waftools/features.py b/waftools/features.py
new file mode 100644
index 0000000000..1385d41dbf
--- /dev/null
+++ b/waftools/features.py
@@ -0,0 +1,69 @@
+from waflib.Options import OptionsContext
+
+class Feature(object):
+ def __init__(self, group, feature):
+ self.group = group
+ self.identifier, self.attributes = feature['name'], feature
+
+ def add_options(self):
+ [self.add_option(option_rule) for option_rule in self.option_rules()]
+
+ def add_option(self, rule):
+ self.group.add_option(self.option(rule['state']),
+ action=rule['action'],
+ default=rule['default'],
+ dest=self.storage(),
+ help=self.help(rule['state']))
+
+ # private
+ def option_rules(self):
+ return {
+ 'autodetect': [
+ {'state': 'disable', 'action': 'store_false', 'default': None},
+ {'state': 'enable', 'action': 'store_true', 'default': None},
+ ],
+ 'disable': [
+ {'state': 'disable', 'action': 'store_false', 'default': False},
+ {'state': 'enable', 'action': 'store_true', 'default': False},
+ ],
+ 'enable': [
+ {'state': 'disable', 'action': 'store_false', 'default': True},
+ ],
+ }[self.behaviour()]
+
+
+ def behaviour(self):
+ if 'default' in self.attributes:
+ return self.attributes['default']
+ else:
+ return 'autodetect'
+
+
+ def option(self, state):
+ return "--{0}-{1}".format(state, self.identifier)
+
+ def help(self, state):
+ return "{0} {1} [{2}]" \
+ .format(state, self.attributes['desc'], self.behaviour())
+
+ def storage(self):
+ return "enable_{0}".format(self.identifier)
+
+def add_feature(group, feature):
+ Feature(group, feature).add_options()
+
+def parse_features(opt, group_name, features):
+ def is_feature(dep):
+ return dep['name'].find('--') >= 0
+
+ def strip_feature(dep):
+ dep['name'] = dep['name'].lstrip('-')
+ return dep
+
+ features = [strip_feature(dep) for dep in features if is_feature(dep)]
+ group = opt.get_option_group(group_name)
+ if not group:
+ group = opt.add_option_group(group_name)
+ [add_feature(group, feature) for feature in features]
+
+OptionsContext.parse_features = parse_features
diff --git a/waftools/fragments/cocoa.m b/waftools/fragments/cocoa.m
new file mode 100644
index 0000000000..6e0e4d32b4
--- /dev/null
+++ b/waftools/fragments/cocoa.m
@@ -0,0 +1,11 @@
+#import <CoreServices/CoreServices.h>
+#import <OpenGL/OpenGL.h>
+#import <Cocoa/Cocoa.h>
+
+int main(int argc, char **argv) {
+ @autoreleasepool {
+ NSArray *ary = @[@1, @2, @3];
+ NSLog(@"test subscripting: %@", ary[0]);
+ NSApplicationLoad();
+ }
+}
diff --git a/waftools/fragments/coreaudio.c b/waftools/fragments/coreaudio.c
new file mode 100644
index 0000000000..c7411311a7
--- /dev/null
+++ b/waftools/fragments/coreaudio.c
@@ -0,0 +1,15 @@
+#include <CoreAudio/CoreAudio.h>
+#include <AudioToolbox/AudioToolbox.h>
+#include <AudioUnit/AudioUnit.h>
+
+int main(int argc, char **argv)
+{
+ AudioComponentDescription desc = (AudioComponentDescription) {
+ .componentType = kAudioUnitType_Output,
+ .componentSubType = kAudioUnitSubType_DefaultOutput,
+ .componentManufacturer = kAudioUnitManufacturer_Apple,
+ };
+
+ AudioComponentFindNext(NULL, &desc);
+ return 0;
+}
diff --git a/waftools/fragments/dvb.c b/waftools/fragments/dvb.c
new file mode 100644
index 0000000000..9deaa1eaab
--- /dev/null
+++ b/waftools/fragments/dvb.c
@@ -0,0 +1,10 @@
+#include <poll.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include <linux/dvb/dmx.h>
+#include <linux/dvb/frontend.h>
+#include <linux/dvb/video.h>
+#include <linux/dvb/audio.h>
+int main(void) {return 0;}
diff --git a/waftools/fragments/ebx.c b/waftools/fragments/ebx.c
new file mode 100644
index 0000000000..b487939c56
--- /dev/null
+++ b/waftools/fragments/ebx.c
@@ -0,0 +1,12 @@
+int main(void) {
+ int x;
+ __asm__ volatile(
+ "xor %0, %0"
+ :"=b"(x)
+ // just adding ebx to clobber list seems unreliable with some
+ // compilers, e.g. Haiku's gcc 2.95
+ );
+ // and the above check does not work for OSX 64 bit...
+ __asm__ volatile("":::"%ebx");
+ return 0;
+}
diff --git a/waftools/fragments/gl_x11.c b/waftools/fragments/gl_x11.c
new file mode 100644
index 0000000000..6c617d43ee
--- /dev/null
+++ b/waftools/fragments/gl_x11.c
@@ -0,0 +1,9 @@
+#include <X11/Xlib.h>
+#include <GL/glx.h>
+#include <GL/gl.h>
+
+int main(int argc, char *argv[]) {
+ glXCreateContext(NULL, NULL, NULL, True);
+ glFinish();
+ return 0;
+}
diff --git a/waftools/fragments/iconv.c b/waftools/fragments/iconv.c
new file mode 100644
index 0000000000..78c963b643
--- /dev/null
+++ b/waftools/fragments/iconv.c
@@ -0,0 +1,30 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <iconv.h>
+#define INBUFSIZE 1024
+#define OUTBUFSIZE 4096
+
+char inbuffer[INBUFSIZE];
+char outbuffer[OUTBUFSIZE];
+
+int main(void) {
+ size_t numread;
+ iconv_t icdsc;
+ char *tocode="UTF-8";
+ char *fromcode="cp1250";
+ if ((icdsc = iconv_open(tocode, fromcode)) != (iconv_t)(-1)) {
+ while ((numread = read(0, inbuffer, INBUFSIZE))) {
+ char *iptr=inbuffer;
+ char *optr=outbuffer;
+ size_t inleft=numread;
+ size_t outleft=OUTBUFSIZE;
+ if (iconv(icdsc, &iptr, &inleft, &optr, &outleft)
+ != (size_t)(-1)) {
+ write(1, outbuffer, OUTBUFSIZE - outleft);
+ }
+ }
+ if (iconv_close(icdsc) == -1)
+ ;
+ }
+ return 0;
+}
diff --git a/waftools/fragments/libavfilter.c b/waftools/fragments/libavfilter.c
new file mode 100644
index 0000000000..4e1986f4a2
--- /dev/null
+++ b/waftools/fragments/libavfilter.c
@@ -0,0 +1,7 @@
+#include <libavfilter/avfilter.h>
+void vf_next_query_format() {}
+int main(void) {
+ avfilter_register_all();
+ vf_next_query_format();
+ return 0;
+}
diff --git a/waftools/fragments/lua.c b/waftools/fragments/lua.c
new file mode 100644
index 0000000000..43d678b476
--- /dev/null
+++ b/waftools/fragments/lua.c
@@ -0,0 +1,24 @@
+#include <stdlib.h>
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+
+// filled on the python side with .format()
+{additional_lua_test_header}
+
+void test_lua(void) {{
+ lua_State *L = luaL_newstate();
+ lua_pushstring(L, "test");
+ lua_setglobal(L, "test");
+}}
+
+void test_other(void) {{
+ // filled on the python side with .format()
+ {additional_lua_test_code}
+}}
+
+int main(void) {{
+ test_lua();
+ test_other();
+ return 0;
+}}
diff --git a/waftools/fragments/lua_libquvi4.c b/waftools/fragments/lua_libquvi4.c
new file mode 100644
index 0000000000..efcf30375a
--- /dev/null
+++ b/waftools/fragments/lua_libquvi4.c
@@ -0,0 +1,3 @@
+ quvi_t q;
+ if (quvi_init(&q) == QUVI_OK)
+ quvi_supported(q, "http://nope");
diff --git a/waftools/fragments/lua_libquvi9.c b/waftools/fragments/lua_libquvi9.c
new file mode 100644
index 0000000000..e25ea1a462
--- /dev/null
+++ b/waftools/fragments/lua_libquvi9.c
@@ -0,0 +1,3 @@
+ quvi_t q = quvi_new();
+ if (quvi_ok(q))
+ quvi_supports(q, "http://nope", QUVI_SUPPORTS_MODE_OFFLINE, QUVI_SUPPORTS_TYPE_MEDIA);
diff --git a/waftools/fragments/mng.c b/waftools/fragments/mng.c
new file mode 100644
index 0000000000..7befc7e895
--- /dev/null
+++ b/waftools/fragments/mng.c
@@ -0,0 +1,7 @@
+#include <libmng.h>
+
+int main(int argc, char **argv)
+{
+ const char * p_ver = mng_version_text();
+ return !p_ver || p_ver[0] == 0;
+}
diff --git a/waftools/fragments/oss_audio.c b/waftools/fragments/oss_audio.c
new file mode 100644
index 0000000000..e23979da97
--- /dev/null
+++ b/waftools/fragments/oss_audio.c
@@ -0,0 +1,11 @@
+#if HAVE_SOUNDCARD_H
+#include <soundcard.h>
+#endif
+
+#if HAVE_SYS_SOUNDCARD_H
+#include <sys/soundcard.h>
+#endif
+
+int main(int argc, char **argv) {
+ return SNDCTL_DSP_SETFRAGMENT;
+}
diff --git a/waftools/fragments/oss_audio_header.c b/waftools/fragments/oss_audio_header.c
new file mode 100644
index 0000000000..980eb69215
--- /dev/null
+++ b/waftools/fragments/oss_audio_header.c
@@ -0,0 +1,13 @@
+#if HAVE_SOUNDCARD_H
+#include <soundcard.h>
+#endif
+
+#if HAVE_SYS_SOUNDCARD_H
+#include <sys/soundcard.h>
+#endif
+
+#ifdef OPEN_SOUND_SYSTEM
+int main(void) {{ return 0; }}
+#else
+#error Not the real thing
+#endif
diff --git a/waftools/fragments/pthreads.c b/waftools/fragments/pthreads.c
new file mode 100644
index 0000000000..6702f36f97
--- /dev/null
+++ b/waftools/fragments/pthreads.c
@@ -0,0 +1,10 @@
+#include <pthread.h>
+static void *func(void *arg) { return arg; }
+int main(void) {
+ pthread_t tid;
+#ifdef PTW32_STATIC_LIB
+ pthread_win32_process_attach_np();
+ pthread_win32_thread_attach_np();
+#endif
+ return pthread_create (&tid, 0, func, 0) != 0;
+}
diff --git a/waftools/fragments/pvr.c b/waftools/fragments/pvr.c
new file mode 100644
index 0000000000..be301e11e5
--- /dev/null
+++ b/waftools/fragments/pvr.c
@@ -0,0 +1,7 @@
+#include <sys/time.h>
+#include <linux/videodev2.h>
+int main(void)
+{
+ struct v4l2_ext_controls ext;
+ return ext.controls->value;
+}
diff --git a/waftools/fragments/vcd_windows.c b/waftools/fragments/vcd_windows.c
new file mode 100644
index 0000000000..8d33127043
--- /dev/null
+++ b/waftools/fragments/vcd_windows.c
@@ -0,0 +1,7 @@
+#include <windows.h>
+#include <ntddcdrm.h>
+
+int main(int argc, char **argv)
+{
+ return 0;
+}
diff --git a/waftools/fragments/wasapi.c b/waftools/fragments/wasapi.c
new file mode 100644
index 0000000000..ef3b3f7866
--- /dev/null
+++ b/waftools/fragments/wasapi.c
@@ -0,0 +1,19 @@
+#define COBJMACROS 1
+#define _WIN32_WINNT 0x600
+#include <malloc.h>
+#include <stdlib.h>
+#include <process.h>
+#include <initguid.h>
+#include <audioclient.h>
+#include <endpointvolume.h>
+#include <mmdeviceapi.h>
+#include <avrt.h>
+ const GUID *check1[] = {
+ &IID_IAudioClient,
+ &IID_IAudioRenderClient,
+ &IID_IAudioClient,
+ &IID_IAudioEndpointVolume,
+ };
+int main(void) {
+ return 0;
+}
diff --git a/waftools/fragments/xf86vm.c b/waftools/fragments/xf86vm.c
new file mode 100644
index 0000000000..195e514d6c
--- /dev/null
+++ b/waftools/fragments/xf86vm.c
@@ -0,0 +1,8 @@
+#include <X11/Xlib.h>
+#include <X11/extensions/xf86vmode.h>
+
+int main(int argc, char **argv)
+{
+ XF86VidModeQueryExtension(0, 0, 0);
+ return 0;
+}
diff --git a/waftools/fragments/xf86xk.c b/waftools/fragments/xf86xk.c
new file mode 100644
index 0000000000..541e7ce3af
--- /dev/null
+++ b/waftools/fragments/xf86xk.c
@@ -0,0 +1,6 @@
+#include <X11/XF86keysym.h>
+
+int main(int argc, char **argv)
+{
+ return XF86XK_AudioPause;
+}
diff --git a/waftools/generators/__init__.py b/waftools/generators/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/waftools/generators/__init__.py
diff --git a/waftools/generators/headers.py b/waftools/generators/headers.py
new file mode 100644
index 0000000000..13f124a2dd
--- /dev/null
+++ b/waftools/generators/headers.py
@@ -0,0 +1,36 @@
+def __get_version__(ctx):
+ import subprocess
+ process = subprocess.Popen(["sh", "./version.sh", "--print"],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ cwd=ctx.srcnode.abspath())
+ process.wait()
+ (version, err) = process.communicate()
+ return version.strip()
+
+def __get_build_date__():
+ import time
+ return time.strftime("%Y-%m-%dT%H:%M:%S", time.gmtime())
+
+def __write_config_h__(ctx):
+ ctx.start_msg("Writing configuration header:")
+ ctx.write_config_header('config.h')
+ ctx.end_msg("config.h", "PINK")
+
+def __write_version_h__(ctx):
+ ctx.start_msg("Writing header:")
+ ctx.env.VERSION = __get_version__(ctx)
+ ctx.define("VERSION", ctx.env.VERSION)
+ ctx.define("BUILDDATE", __get_build_date__())
+ ctx.write_config_header("version.h")
+ ctx.end_msg("version.h", "PINK")
+
+def __add_mplayer_defines__(ctx):
+ from sys import argv
+ ctx.define("CONFIGURATION", " ".join(argv))
+ ctx.define("MPLAYER_CONFDIR", ctx.env.CONFDIR)
+
+def configure(ctx):
+ __add_mplayer_defines__(ctx)
+ __write_config_h__(ctx)
+ __write_version_h__(ctx)
diff --git a/waftools/generators/sources.py b/waftools/generators/sources.py
new file mode 100644
index 0000000000..1248ad90b4
--- /dev/null
+++ b/waftools/generators/sources.py
@@ -0,0 +1,37 @@
+from waflib.Build import BuildContext
+import os
+
+def __file2string_cmd__(ctx):
+ return "${{BIN_PERL}} {0}/TOOLS/file2string.pl ${{SRC}} > ${{TGT}}" \
+ .format(ctx.srcnode.abspath())
+
+def __matroska_cmd__(ctx, argument):
+ return "${{BIN_PERL}} {0}/TOOLS/matroska.pl {1} ${{SRC}} > ${{TGT}}" \
+ .format(ctx.srcnode.abspath(), argument)
+
+def __file2string__(ctx, **kwargs):
+ ctx(
+ rule = __file2string_cmd__(ctx),
+ before = ("c",),
+ name = os.path.basename(kwargs['target']),
+ **kwargs
+ )
+
+def __matroska_header__(ctx, **kwargs):
+ ctx(
+ rule = __matroska_cmd__(ctx, '--generate-header'),
+ before = ("c",),
+ name = os.path.basename(kwargs['target']),
+ **kwargs
+ )
+
+def __matroska_definitions__(ctx, **kwargs):
+ ctx(
+ rule = __matroska_cmd__(ctx, '--generate-definitions'),
+ before = ("c",),
+ **kwargs
+ )
+
+BuildContext.file2string = __file2string__
+BuildContext.matroska_header = __matroska_header__
+BuildContext.matroska_definitions = __matroska_definitions__
diff --git a/waftools/inflectors.py b/waftools/inflectors.py
new file mode 100644
index 0000000000..3641de8818
--- /dev/null
+++ b/waftools/inflectors.py
@@ -0,0 +1,26 @@
+import re
+
+class DependencyInflector(object):
+ def __init__(self, dependency):
+ self.dep = dependency
+
+ def storage_key(self):
+ return self.__underscore__(self.dep)
+
+ def define_key(self):
+ return ("have_" + self.storage_key()).upper()
+
+ def define_dict(self):
+ return {'define_name': self.define_key()}
+
+ def storage_dict(self):
+ return {'uselib_store': self.storage_key()}
+
+ def __underscore__(self, word):
+ """ Converts a word "into_it_s_underscored_version"
+ Convert any "CamelCased" or "ordinary Word" into an
+ "underscored_word"."""
+
+ return re.sub('[^A-Z^a-z^0-9]+', '_', \
+ re.sub('([a-z\d])([A-Z])', '\\1_\\2', \
+ re.sub('([A-Z]+)([A-Z][a-z])', '\\1_\\2', re.sub('::', '/', word)))).lower()
diff --git a/waftools/waf_customizations.py b/waftools/waf_customizations.py
new file mode 100644
index 0000000000..b6798d4235
--- /dev/null
+++ b/waftools/waf_customizations.py
@@ -0,0 +1,46 @@
+from waflib.Configure import conf
+
+@conf
+def get_config_header(self, defines=True, headers=False, define_prefix=''):
+ """
+ Only difference is it outputs `#define VAR 0` or `#define VAR value`
+ instead of `#undef VAR` or `#define VAR val`.
+ """
+ from waflib.Tools.c_config import DEFKEYS, INCKEYS
+ lst = []
+ if headers:
+ for x in self.env[INCKEYS]:
+ lst.append('#include <%s>' % x)
+
+ if defines:
+ for x in self.env[DEFKEYS]:
+ val = self.is_defined(x) and self.get_define(x) or "0"
+ lst.append('#define %s %s' % (define_prefix + x, val))
+
+ return "\n".join(lst)
+
+from waflib import TaskGen
+
+@TaskGen.extension('.m')
+def m_hook(self, node):
+ """
+ Makes waf call the c compiler for objective-c files
+ """
+ return self.create_compiled_task('c', node)
+
+def build(ctx):
+ from waflib import Task
+ cls = Task.classes['cprogram']
+ class cprogram(cls):
+ run_str = cls.hcode + '${LAST_LINKFLAGS}'
+
+ cls = Task.classes['macplist']
+ class macplist(cls):
+ def run(self):
+ from waflib import Utils
+ if getattr(self, 'code', None):
+ txt = self.code
+ else:
+ txt = self.inputs[0].read()
+ txt = Utils.subst_vars(txt, self.env)
+ self.outputs[0].write(txt)
diff --git a/wscript b/wscript
new file mode 100644
index 0000000000..bd86c98bb5
--- /dev/null
+++ b/wscript
@@ -0,0 +1,759 @@
+# vi: ft=python
+
+import sys, os, re
+sys.path.insert(0, os.path.join(os.getcwd(), 'waftools'))
+from waflib.Configure import conf
+from waflib import Utils
+from waftools.checks.generic import *
+from waftools.checks.custom import *
+
+build_options = [
+ {
+ 'name': '--static-build',
+ 'desc': 'static build',
+ 'default': 'disable',
+ 'func': check_true
+ }, {
+ 'name': '--build-date',
+ 'desc': 'whether to include binary compile time',
+ 'default': 'enable',
+ 'func': check_true
+ }, {
+ 'name': '--debug-build',
+ 'desc': 'whether to compile-in debugging information',
+ 'default': 'enable',
+ 'func': check_true
+ }, {
+ 'name': '--manpage-build',
+ 'desc': 'manpage generation',
+ 'func': check_ctx_vars('RST2MAN')
+ }, {
+ 'name': '--pdf-build',
+ 'desc': 'pdf manual generation',
+ 'func': check_ctx_vars('RST2LATEX', 'PDFLATEX'),
+ 'default': 'disable'
+ }, {
+ 'name': 'libdl',
+ 'desc': 'dynamic loader',
+ 'func': check_libs(['dl'], check_statement('dlfcn.h', 'dlopen("", 0)'))
+ }, {
+ 'name': 'dlopen',
+ 'desc': 'dlopen',
+ 'deps_any': [ 'libdl', 'os-win32', 'os-cygwin' ],
+ 'func': check_true
+ }, {
+ 'name': '--vf-dlopen-filters',
+ 'desc': 'compilation of default filters for vf_dlopen',
+ 'deps': [ 'dlopen' ],
+ 'default': 'disable',
+ 'func': check_true
+ }, {
+ 'name': '--macosx-bundle',
+ 'desc': 'compilation of a Mac OS X Application bundle',
+ 'deps': [ 'os-darwin' ],
+ 'default': 'disable',
+ 'func': check_true
+ }, {
+ 'name': 'win32-executable',
+ 'desc': 'w32 executable',
+ 'deps_any': [ 'os-win32', 'os-cygwin'],
+ 'func': check_ctx_vars('WINDRES')
+ }
+]
+
+main_dependencies = [
+ {
+ 'name': 'noexecstack',
+ 'desc': 'compiler support for noexecstack',
+ 'func': check_cc(linkflags='-Wl,-z,noexecstack')
+ }, {
+ 'name': 'noexecstack',
+ 'desc': 'linker support for --nxcompat --no-seh --dynamicbase',
+ 'func': check_cc(linkflags=['-Wl,--nxcompat', '-Wl,--no-seh', '-Wl,--dynamicbase'])
+ }, {
+ 'name': 'ebx_available',
+ 'desc': 'ebx availability',
+ 'func': check_cc(fragment=load_fragment('ebx.c'))
+ } , {
+ 'name': 'libm',
+ 'desc': '-lm',
+ 'func': check_cc(lib='m')
+ }, {
+ 'name': 'nanosleep',
+ 'desc': 'nanosleep',
+ 'func': check_statement('time.h', 'nanosleep(0,0)')
+ }, {
+ 'name': 'sys-mman-h',
+ 'desc': 'mman.h',
+ 'func': check_statement('sys/mman.h', 'mmap(0, 0, 0, 0, 0, 0)')
+ }, {
+ 'name': '--pthreads',
+ 'desc': 'POSIX threads',
+ 'func': check_pthreads,
+ }, {
+ 'name': 'librt',
+ 'desc': 'linking with -lrt',
+ 'deps': [ 'pthreads' ],
+ 'func': check_cc(lib='rt')
+ }, {
+ 'name': '--iconv',
+ 'desc': 'iconv',
+ 'func': check_iconv,
+ 'req': True,
+ 'fmsg': "Unable to find iconv which should be part of a standard \
+compilation environment. Aborting. If you really mean to compile without \
+iconv support use --disable-iconv.",
+ }, {
+ 'name': 'dos-paths',
+ 'desc': 'w32/dos paths',
+ 'deps_any': [ 'os-win32', 'os-cygwin' ],
+ 'func': check_true
+ }, {
+ 'name': 'priority',
+ 'desc': 'w32 priority API',
+ 'deps_any': [ 'os-win32', 'os-cygwin'],
+ 'func': check_true
+ }, {
+ 'name': 'stream-cache',
+ 'desc': 'stream cache',
+ 'deps': [ 'pthreads' ],
+ 'func': check_true
+ }, {
+ 'name': 'soundcard',
+ 'desc': 'soundcard.h',
+ 'func': check_headers('soundcard.h', 'sys/soundcard.h')
+ }, {
+ 'name': 'videoio',
+ 'desc': 'videoio.h',
+ 'func': check_headers('sys/videoio.h')
+ }, {
+ 'name': '--terminfo',
+ 'desc': 'terminfo',
+ 'func': check_libs(['ncurses', 'ncursesw'],
+ check_statement('term.h', 'setupterm(0, 1, 0)')),
+ }, {
+ 'name': '--termcap',
+ 'desc': 'termcap',
+ 'deps_neg': ['terminfo'],
+ 'func': check_libs(['ncurses', 'tinfo', 'termcap'],
+ check_statement('term.h', 'tgetent(0, 0)')),
+ }, {
+ 'name': '--termios',
+ 'desc': 'termios',
+ 'func': check_headers('termios.h', 'sys/termios.h'),
+ }, {
+ 'name': '--shm',
+ 'desc': 'shm',
+ 'func': check_statement('sys/shm.h',
+ 'shmget(0, 0, 0); shmat(0, 0, 0); shmctl(0, 0, 0)')
+ }, {
+ 'name': 'posix-select',
+ 'desc': 'POSIX select()',
+ 'func': check_statement('sys/select.h', """
+ int rc;
+ rc = select(0, (fd_set *)(0), (fd_set *)(0), (fd_set *)(0),
+ (struct timeval *)(0))""")
+ }, {
+ 'name': 'glob',
+ 'desc': 'glob()',
+ 'func': check_statement('glob.h', 'glob("filename", 0, 0, 0)')
+ }, {
+ 'name': 'glob-win32-replacement',
+ 'desc': 'glob() win32 replacement',
+ 'deps_neg': [ 'glob' ],
+ 'deps_any': [ 'os-win32', 'os-cygwin' ],
+ 'func': check_true
+ }, {
+ 'name': 'setmode',
+ 'desc': 'setmode()',
+ 'func': check_statement('io.h', 'setmode(0, 0)')
+ }, {
+ 'name': 'sys-sysinfo-h',
+ 'desc': 'sys/sysinfo.h',
+ 'func': check_statement('sys/sysinfo.h',
+ 'struct sysinfo s_info; s_info.mem_unit=0; sysinfo(&s_info)')
+ }, {
+ 'name': '--libguess',
+ 'desc': 'libguess support',
+ 'func': check_pkg_config('libguess', '>= 1.0'),
+ }, {
+ 'name': '--libsmbclient',
+ 'desc': 'Samba support',
+ 'deps': [ 'libdl' ],
+ 'func': check_pkg_config('smbclient', '>= 0.2.0'),
+ 'module': 'input',
+ }, {
+ 'name': '--libquvi4',
+ 'desc': 'libquvi 0.4.x support',
+ 'func': check_pkg_config('libquvi', '>= 0.4.1'),
+ }, {
+ 'name': '--libquvi9',
+ 'desc': 'libquvi 0.9.x support',
+ 'deps_neg': [ 'libquvi4' ],
+ 'func': check_pkg_config('libquvi-0.9', '>= 0.9.0'),
+ }, {
+ 'name': '--libass',
+ 'desc': 'SSA/ASS support',
+ 'func': check_pkg_config('libass'),
+ 'req': True,
+ 'fmsg': "Unable to find development files for libass. Aborting. \
+If you really mean to compile without libass support use --disable-libass."
+ }, {
+ 'name': '--libass-osd',
+ 'desc': 'libass OSD support',
+ 'deps': [ 'libass' ],
+ 'func': check_true,
+ }, {
+ 'name': 'dummy-osd',
+ 'desc': 'dummy OSD support',
+ 'deps_neg': [ 'libass-osd' ],
+ 'func': check_true,
+ } , {
+ 'name': 'zlib',
+ 'desc': 'zlib',
+ 'func': check_libs(['z'],
+ check_statement('zlib.h', 'inflate(0, Z_NO_FLUSH)')),
+ 'req': True,
+ 'fmsg': 'Unable to find development files for zlib.'
+ } , {
+ 'name' : '--encoding',
+ 'desc' : 'Encoding',
+ 'func': check_true,
+ }, {
+ 'name' : '--joystick',
+ 'desc' : 'joystick',
+ 'func': check_cc(header_name='linux/joystick.h'),
+ 'default': 'disable'
+ }, {
+ 'name' : '--lirc',
+ 'desc' : 'lirc',
+ 'func': check_cc(header_name='lirc/lirc_client.h', lib='lirc_client'),
+ }, {
+ 'name' : '--lircc',
+ 'desc' : 'lircc',
+ 'func': check_cc(header_name='lirc/lircc.h', lib='lircc'),
+ }, {
+ 'name' : '--vcd',
+ 'desc' : 'VCD support',
+ 'deps_any': [ 'os-linux', 'os-freebsd', 'os-netbsd', 'os-openbsd', 'os-darwin' ],
+ 'func': check_true,
+ 'os_specific_checks': {
+ 'os-win32': {
+ 'func': check_cc(fragment=load_fragment('vcd_windows.c'))
+ }
+ }
+ }, {
+ 'name': '--libbluray',
+ 'desc': 'Bluray support',
+ 'func': check_pkg_config('libbluray', '>= 0.2.1'),
+ }, {
+ 'name': '--dvdread',
+ 'desc': 'dvdread support',
+ 'func': check_pkg_config('dvdread', '>= 4.1.0'),
+ }, {
+ 'name': '--cdda',
+ 'desc': 'cdda support (libcdio)',
+ 'func': check_pkg_config('libcdio_paranoia'),
+ }, {
+ 'name': '--enca',
+ 'desc': 'ENCA support',
+ 'func': check_statement('enca.h', 'enca_get_languages(NULL)', lib='enca'),
+ }, {
+ 'name': '--mpg123',
+ 'desc': 'mpg123 support',
+ 'func': check_pkg_config('libmpg123', '>= 1.2.0'),
+ }, {
+ 'name': '--ladspa',
+ 'desc': 'LADSPA plugin support',
+ 'func': check_statement('ladspa.h', 'LADSPA_Descriptor ld = {0}'),
+ }, {
+ 'name': '--libbs2b',
+ 'desc': 'libbs2b audio filter support',
+ 'func': check_pkg_config('libbs2b'),
+ }, {
+ 'name': '--lcms2',
+ 'desc': 'LCMS2 support',
+ 'func': check_pkg_config('lcms2'),
+ }
+]
+
+libav_pkg_config_checks = [
+ 'libavutil', '> 51.73.0',
+ 'libavcodec', '> 54.34.0',
+ 'libavformat', '> 54.19.0',
+ 'libswscale', '>= 2.0.0'
+]
+
+libav_dependencies = [
+ {
+ 'name': 'libav',
+ 'desc': 'libav/ffmpeg',
+ 'func': check_pkg_config(*libav_pkg_config_checks),
+ 'req': True,
+ 'fmsg': "Unable to find development files for some of the required \
+Libav libraries ({0}). Aborting.".format(" ".join(libav_pkg_config_checks))
+ }, {
+ 'name': '--libavresample',
+ 'desc': 'libavresample',
+ 'func': check_pkg_config('libavresample', '>= 1.0.0'),
+ }, {
+ 'name': 'avresample-set-channel-mapping',
+ 'desc': 'libavresample channel mapping API',
+ 'deps': [ 'libavresample' ],
+ 'func': check_statement('libavresample/avresample.h',
+ 'avresample_set_channel_mapping(NULL, NULL)',
+ use='libavresample'),
+ }, {
+ 'name': '--libswresample',
+ 'desc': 'libswresample',
+ 'func': check_pkg_config('libswresample', '>= 0.17.102'),
+ }, {
+ 'name': 'resampler',
+ 'desc': 'usable resampler found',
+ 'deps_any': [ 'libavresample', 'libswresample' ],
+ 'func': check_true,
+ 'req': True,
+ 'fmsg': 'No resampler found. Install libavresample or libswresample (FFmpeg).'
+ }, {
+ 'name': 'avcodec-new-vdpau-api',
+ 'desc': 'libavcodec new vdpau API',
+ 'func': check_statement('libavutil/pixfmt.h',
+ 'int x = AV_PIX_FMT_VDPAU',
+ use='libav'),
+ }, {
+ 'name': 'avcodec-chroma-pos-api',
+ 'desc': 'libavcodec avcodec_enum_to_chroma_pos API',
+ 'func': check_statement('libavcodec/avcodec.h', """int x, y;
+ avcodec_enum_to_chroma_pos(&x, &y, AVCHROMA_LOC_UNSPECIFIED)""",
+ use='libav')
+ }, {
+ 'name': 'avutil-qp-api',
+ 'desc': 'libavutil QP API',
+ 'func': check_statement('libavutil/frame.h',
+ 'av_frame_get_qp_table(NULL, NULL, NULL)',
+ use='libav')
+ }, {
+ 'name': 'avutil-refcounting',
+ 'desc': 'libavutil ref-counting API',
+ 'func': check_statement('libavutil/frame.h', 'av_frame_unref(NULL)',
+ use='libav'),
+ } , {
+ 'name': 'av-opt-set-int-list',
+ 'desc': 'libavutil av_opt_set_int_list() API',
+ 'func': check_statement('libavutil/opt.h',
+ 'av_opt_set_int_list(0,0,(int*)0,0,0)',
+ use='libav')
+ }, {
+ 'name': '--libavfilter',
+ 'desc': 'libavfilter',
+ 'func': compose_checks(
+ check_pkg_config('libavfilter'),
+ check_cc(fragment=load_fragment('libavfilter.c'),
+ use='libavfilter')),
+ }, {
+ 'name': '--vf-lavfi',
+ 'desc': 'using libavfilter through vf_lavfi',
+ 'deps': [ 'libavfilter', 'avutil-refcounting' ],
+ 'func': check_true
+ }, {
+ 'name': '--af-lavfi',
+ 'desc': 'using libavfilter through af_lavfi',
+ 'deps': [ 'libavfilter', 'av-opt-set-int-list' ],
+ 'func': check_true
+ }, {
+ 'name': '--libavdevice',
+ 'desc': 'libavdevice',
+ 'func': check_pkg_config('libavdevice', '>= 54.0.0'),
+ }, {
+ 'name': '--libpostproc',
+ 'desc': 'libpostproc',
+ 'func': check_pkg_config('libpostproc', '>= 52.0.0'),
+ }
+]
+
+audio_output_features = [
+ {
+ 'name': '--sdl2',
+ 'desc': 'SDL2',
+ 'func': check_pkg_config('sdl2')
+ }, {
+ 'name': '--sdl',
+ 'desc': 'SDL (1.x)',
+ 'deps_neg': [ 'sdl2' ],
+ 'func': check_pkg_config('sdl')
+ }, {
+ 'name': '--oss-audio',
+ 'desc': 'OSS audio output',
+ 'func': check_oss
+ }, {
+ 'name': '--audio-select',
+ 'desc': 'audio select()',
+ 'deps': [ 'posix-select', 'oss-audio' ],
+ 'func': check_true,
+ }, {
+ 'name': '--rsound',
+ 'desc': 'RSound audio output',
+ 'func': check_statement('rsound.h', 'rsd_init(NULL)', lib='rsound')
+ }, {
+ 'name': '--sndio',
+ 'desc': 'sndio audio input/output',
+ 'func': check_statement('sndio.h',
+ 'struct sio_par par; sio_initpar(&par)', lib='sndio')
+ }, {
+ 'name': '--pulse',
+ 'desc': 'PulseAudio audio output',
+ 'func': check_pkg_config('libpulse', '>= 0.9')
+ }, {
+ 'name': '--portaudio',
+ 'desc': 'PortAudio audio output',
+ 'deps': [ 'pthreads' ],
+ 'func': check_pkg_config('portaudio-2.0', '>= 19'),
+ }, {
+ 'name': '--jack',
+ 'desc': 'JACK audio output',
+ 'func': check_pkg_config('jack'),
+ }, {
+ 'name': '--openal',
+ 'desc': 'OpenAL audio output',
+ 'func': check_pkg_config('openal', '>= 1.13'),
+ 'default': 'disable'
+ }, {
+ 'name': '--alsa',
+ 'desc': 'ALSA audio output',
+ 'func': check_pkg_config('alsa'),
+ }, {
+ 'name': '--coreaudio',
+ 'desc': 'CoreAudio audio output',
+ 'func': check_cc(
+ fragment=load_fragment('coreaudio.c'),
+ framework_name=['CoreAudio', 'AudioUnit', 'AudioToolbox'])
+ }, {
+ 'name': '--dsound',
+ 'desc': 'DirectSound audio output',
+ 'func': check_cc(header_name='dsound.h'),
+ }, {
+ 'name': '--wasapi',
+ 'desc': 'WASAPI audio output',
+ 'func': check_cc(fragment=load_fragment('wasapi.c'), lib='ole32'),
+ }
+]
+
+video_output_features = [
+ {
+ 'name': '--cocoa',
+ 'desc': 'Cocoa',
+ 'func': check_cc(
+ fragment=load_fragment('cocoa.m'),
+ compile_filename='test.m',
+ framework_name=['Cocoa', 'IOKit', 'OpenGL'])
+ } , {
+ 'name': '--wayland',
+ 'desc': 'Wayland',
+ 'func': check_pkg_config('wayland-client', '>= 1.2.0',
+ 'wayland-cursor', '>= 1.2.0',
+ 'xkbcommon', '>= 0.3.0'),
+ } , {
+ 'name': '--x11',
+ 'desc': 'X11',
+ 'func': check_pkg_config('x11'),
+ } , {
+ 'name': '--xss',
+ 'desc': 'Xss screensaver extensions',
+ 'deps': [ 'x11' ],
+ 'func': check_statement('X11/extensions/scrnsaver.h',
+ 'XScreenSaverSuspend(NULL, True)', use='x11', lib='Xss'),
+ } , {
+ 'name': '--xext',
+ 'desc': 'X extensions',
+ 'deps': [ 'x11' ],
+ 'func': check_pkg_config('xext'),
+ } , {
+ 'name': '--xv',
+ 'desc': 'Xv video output',
+ 'deps': [ 'x11' ],
+ 'func': check_pkg_config('xv'),
+ } , {
+ 'name': '--xinerama',
+ 'desc': 'Xinerama',
+ 'deps': [ 'x11' ],
+ 'func': check_pkg_config('xinerama'),
+ }, {
+ 'name': '--xf86vm',
+ 'desc': 'Xxf86vm',
+ 'deps': [ 'x11' ],
+ 'func': check_cc(fragment=load_fragment('xf86vm.c'),
+ lib='Xxf86vm', use='x11')
+ } , {
+ 'name': '--xf86xk',
+ 'desc': 'XF86keysym',
+ 'deps': [ 'x11' ],
+ 'func': check_cc(fragment=load_fragment('xf86xk.c'))
+ } , {
+ 'name': '--gl-cocoa',
+ 'desc': 'OpenGL Cocoa Backend',
+ 'deps': [ 'cocoa' ],
+ 'func': check_true
+ } , {
+ 'name': '--gl-x11',
+ 'desc': 'OpenGL X11 Backend',
+ 'deps': [ 'x11' ],
+ 'func': check_libs(['GL', 'GL Xdamage'],
+ check_cc(fragment=load_fragment('gl_x11.c'),
+ use=['x11', 'libdl', 'pthreads']))
+ } , {
+ 'name': '--gl-wayland',
+ 'desc': 'OpenGL Wayland Backend',
+ 'deps': [ 'wayland' ],
+ 'func': check_pkg_config('wayland-egl', '>= 9.0.0',
+ 'egl', '>= 9.0.0')
+ } , {
+ 'name': '--gl-win32',
+ 'desc': 'OpenGL Win32 Backend',
+ 'func': check_statement('windows.h', 'wglCreateContext(0)',
+ lib='opengl32')
+ } , {
+ 'name': '--gl',
+ 'desc': 'OpenGL video outputs',
+ 'deps_any': [ 'gl-cocoa', 'gl-x11', 'gl-win32', 'gl-wayland' ],
+ 'func': check_true
+ } , {
+ 'name': '--corevideo',
+ 'desc': 'CoreVideo',
+ 'deps': [ 'gl', 'gl-cocoa' ],
+ 'func': check_statement('QuartzCore/CoreVideo.h',
+ 'CVOpenGLTextureCacheCreate(0, 0, 0, 0, 0, 0)',
+ framework_name=['QuartzCore'])
+ } , {
+ 'name': '--vdpau',
+ 'desc': 'VDPAU acceleration',
+ 'deps': [ 'x11' ],
+ 'func': check_pkg_config('vdpau', '>= 0.2'),
+ } , {
+ 'name': '--vdpau-gl-x11',
+ 'desc': 'VDPAU with OpenGL/X11',
+ 'deps': [ 'vdpau', 'gl-x11' ],
+ 'func': check_true,
+ }, {
+ 'name': '--vaapi',
+ 'desc': 'VAAPI acceleration',
+ 'deps': [ 'x11', 'libdl' ],
+ 'func': check_pkg_config(
+ 'libva', '>= 0.32.0', 'libva-x11', '>= 0.32.0'),
+ }, {
+ 'name': '--vaapi-vpp',
+ 'desc': 'VAAPI VPP',
+ 'deps': [ 'vaapi' ],
+ 'func': check_pkg_config('libva', '>= 0.34.0'),
+ }, {
+ 'name': '--vaapi-glx',
+ 'desc': 'VAAPI GLX',
+ 'deps': [ 'vaapi', 'gl-x11' ],
+ 'func': check_pkg_config('libva-glx', '>= 0.32.0'),
+ }, {
+ 'name': '--caca',
+ 'desc': 'CACA',
+ 'func': check_pkg_config('caca', '>= 0.99.beta18'),
+ }, {
+ 'name': '--dvb',
+ 'desc': 'DVB',
+ 'func': check_cc(fragment=load_fragment('dvb.c')),
+ } , {
+ 'name': '--dvbin',
+ 'desc': 'DVB input module',
+ 'deps': [ 'dvb' ],
+ 'func': check_true,
+ }, {
+ 'name': '--jpeg',
+ 'desc': 'JPEG support',
+ 'func': check_cc(header_name=['stdio.h', 'jpeglib.h'],
+ lib='jpeg', use='libm'),
+ }, {
+ 'name': '--direct3d',
+ 'desc': 'Direct3D support',
+ 'func': check_cc(header_name='d3d9.h'),
+ }
+]
+
+hwaccel_features = [
+ {
+ 'name': '--vaapi-hwaccel',
+ 'desc': 'libavcodec VAAPI hwaccel',
+ 'deps': [ 'vaapi' ],
+ 'func': check_true,
+ } , {
+ 'name': '--vda-hwaccel',
+ 'desc': 'libavcodec VDA hwaccel',
+ 'deps': [ 'corevideo', 'avutil-refcounting'],
+ 'func': compose_checks(
+ check_headers('VideoDecodeAcceleration/VDADecoder.h'),
+ check_statement('libavcodec/vda.h',
+ 'ff_vda_create_decoder(NULL, NULL, NULL)',
+ framework='IOSurface',
+ use='libav')),
+ } , {
+ 'name': 'vda-libavcodec-refcounting',
+ 'desc': "libavcodec VDA ref-counted CVPixelBuffers",
+ 'deps': [ 'vda-hwaccel' ],
+ 'func': check_statement ('libavcodec/vda.h',
+ """struct vda_context a = (struct vda_context) {
+ .use_ref_buffer = 1 }""", use='libav')
+ }, {
+ 'name': '--vdpau-decoder',
+ 'desc': 'VDPAU decoder (old)',
+ 'deps': [ 'vdpau' ],
+ 'deps_neg': ['avcodec-new-vdpau-api'],
+ 'func': check_true,
+ }, {
+ 'name': '--vdpau-hwaccel',
+ 'desc': 'libavcodec VDPAU hwaccel (new)',
+ 'deps': [ 'vdpau', 'avcodec-new-vdpau-api' ],
+ 'func': check_true,
+ }
+]
+
+radio_and_tv_features = [
+ {
+ 'name': '--radio',
+ 'desc': 'Radio interface',
+ 'func': check_true,
+ 'default': 'disable'
+ }, {
+ 'name': '--radio-capture',
+ 'desc': 'Radio capture (through PCI/line-in)',
+ 'func': check_true,
+ 'deps': [ 'radio' ],
+ 'deps_any': [ 'alsa', 'oss-audio', 'sndio'],
+ }, {
+ 'name': '--radio-v4l2',
+ 'desc': 'Video4Linux2 radio interface',
+ 'func': check_cc(header_name='linux/videodev2.h'),
+ 'default': 'disable'
+ }, {
+ 'name': '--tv',
+ 'desc': 'TV interface',
+ 'func': check_true,
+ }, {
+ 'name': '--tv-v4l2',
+ 'desc': 'Video4Linux2 TV interface',
+ 'func': check_cc(header_name=['sys/time.h', 'linux/videodev2.h'])
+ ## XXX: what the fuck is up with this needing: sys_videoio_h?
+ }, {
+ 'name': '--libv4l2',
+ 'desc': 'libv4l2 support',
+ 'func': check_pkg_config('libv4l2'),
+ }, {
+ 'name': '--pvr',
+ 'desc': 'Video4Linux2 MPEG PVR interface',
+ 'func': check_cc(fragment='pvr.c'),
+ }, {
+ 'name': '--audio-input',
+ 'desc': 'audio input support',
+ 'deps_any': [ 'radio-capture', 'tv-v4l2' ],
+ 'func': check_true
+ }
+]
+
+scripting_features = [
+ {
+ 'name' : '--lua',
+ 'desc' : 'Lua',
+ 'func': check_lua,
+ }
+]
+
+_INSTALL_DIRS_LIST = [
+ ('bindir', '${PREFIX}/bin', 'binary files'),
+ ('libdir', '${PREFIX}/lib', 'library files'),
+ ('confdir', '${PREFIX}/etc/mpv', 'configuration files'),
+
+ ('datadir', '${PREFIX}/share', 'data files'),
+ ('mandir', '${DATADIR}/man', 'man pages '),
+ ('docdir', '${DATADIR}/doc/mpv', 'documentation files'),
+]
+
+def options(opt):
+ opt.load('compiler_c')
+ opt.load('waf_customizations')
+ opt.load('features')
+
+ group = opt.get_option_group("build and install options")
+ for ident, default, desc in _INSTALL_DIRS_LIST:
+ group.add_option('--{0}'.format(ident),
+ type = 'string',
+ dest = ident,
+ default = default,
+ help = 'directory for installing {0} [{1}]' \
+ .format(desc, default))
+
+ opt.parse_features('build and install options', build_options)
+ optional_features = main_dependencies + libav_dependencies
+ opt.parse_features('optional feaures', optional_features)
+ opt.parse_features('audio outputs', audio_output_features)
+ opt.parse_features('video outputs', video_output_features)
+ opt.parse_features('hwaccels', hwaccel_features)
+ opt.parse_features('radio/tv features', radio_and_tv_features)
+ opt.parse_features('scripting', scripting_features)
+
+ group = opt.get_option_group("scripting")
+ group.add_option('--lua',
+ type = 'string',
+ dest = 'LUA_VER',
+ help = "select Lua package which should be autodetected. Choices: 51 51deb 52 52deb luajit")
+
+@conf
+def is_debug_build(ctx):
+ return getattr(ctx.options, 'enable_debug-build')
+
+def configure(ctx):
+ ctx.check_waf_version(mini='1.7.13')
+ target = os.environ.get('TARGET')
+ (cc, pkg_config, windres) = ('cc', 'pkg-config', 'windres')
+
+ if target:
+ cc = '-'.join([target, 'gcc'])
+ pkg_config = '-'.join([target, pkg_config])
+ windres = '-'.join([target, windres])
+
+ ctx.find_program(cc, var='CC')
+ ctx.find_program(pkg_config, var='PKG_CONFIG')
+ ctx.find_program('perl', var='BIN_PERL')
+ ctx.find_program('rst2man', var='RST2MAN', mandatory=False)
+ ctx.find_program('rst2latex', var='RST2LATEX', mandatory=False)
+ ctx.find_program('pdflatex', var='PDFLATEX', mandatory=False)
+ ctx.find_program(windres, var='WINDRES', mandatory=False)
+
+ for ident, _, _ in _INSTALL_DIRS_LIST:
+ varname = ident.upper()
+ ctx.env[varname] = getattr(ctx.options, ident)
+
+ # keep substituting vars, until the paths are fully expanded
+ while re.match('\$\{([^}]+)\}', ctx.env[varname]):
+ ctx.env[varname] = Utils.subst_vars(ctx.env[varname], ctx.env)
+
+ ctx.load('compiler_c')
+ ctx.load('waf_customizations')
+ ctx.load('dependencies')
+ ctx.load('detections.compiler')
+ ctx.load('detections.cpu')
+ ctx.load('detections.devices')
+
+ ctx.parse_dependencies(build_options)
+ ctx.parse_dependencies(main_dependencies)
+ ctx.parse_dependencies(audio_output_features)
+ ctx.parse_dependencies(video_output_features)
+ ctx.parse_dependencies(libav_dependencies)
+ ctx.parse_dependencies(hwaccel_features)
+ ctx.parse_dependencies(radio_and_tv_features)
+
+ if ctx.options.LUA_VER:
+ ctx.options.enable_lua = True
+
+ ctx.parse_dependencies(scripting_features)
+
+ ctx.load('generators.headers')
+
+ if not ctx.dependency_satisfied('build-date'):
+ ctx.env.CFLAGS += ['-DNO_BUILD_TIMESTAMPS']
+
+def build(ctx):
+ ctx.load('wscript_build')
diff --git a/wscript_build.py b/wscript_build.py
new file mode 100644
index 0000000000..38ea141b3d
--- /dev/null
+++ b/wscript_build.py
@@ -0,0 +1,459 @@
+def _add_rst_manual_dependencies(ctx):
+ manpage_sources_basenames = """
+ options.rst ao.rst vo.rst af.rst vf.rst encode.rst
+ input.rst osc.rst lua.rst changes.rst""".split()
+
+ manpage_sources = ['DOCS/man/en/'+x for x in manpage_sources_basenames]
+
+ for manpage_source in manpage_sources:
+ ctx.add_manual_dependency(
+ ctx.path.find_node('DOCS/man/en/mpv.rst'),
+ ctx.path.find_node(manpage_source))
+
+def _build_man(ctx):
+ ctx(
+ name = 'rst2man',
+ target = 'DOCS/man/en/mpv.1',
+ source = 'DOCS/man/en/mpv.rst',
+ rule = '${RST2MAN} ${SRC} ${TGT}',
+ install_path = ctx.env.MANDIR)
+
+ _add_rst_manual_dependencies(ctx)
+
+def _build_pdf(ctx):
+ from waflib import TaskGen
+
+ TaskGen.declare_chain(
+ name = 'rst2latex',
+ rule = '${RST2LATEX} ${RST2LATEX_FLAGS} ${SRC} ${TGT}',
+ ext_in = '.rst',
+ ext_out = '.tex' )
+
+ TaskGen.declare_chain(
+ name = 'pdflatex',
+ rule = '${PDFLATEX} ${PDFLATEX_FLAGS} ${SRC}; ' * 2,
+ ext_in = '.tex',
+ ext_out = '.pdf',
+ shell = True )
+
+ ctx.env.RST2LATEX_FLAGS = [
+ '--config=' + ctx.srcnode.abspath() + '/DOCS/man/docutils.conf'
+ ]
+
+ ctx.env.PDFLATEX_FLAGS = [
+ '--interaction=batchmode',
+ '--output-directory=DOCS/man/en/',
+ '--jobname=mpv'
+ ]
+
+ ctx(source = 'DOCS/man/en/mpv.rst')
+ _add_rst_manual_dependencies(ctx)
+ ctx.install_files(ctx.env.DOCDIR, ['DOCS/man/en/mpv.pdf'])
+
+def build(ctx):
+ ctx.load('waf_customizations')
+ ctx.load('generators.sources')
+
+ ctx.file2string(
+ source = "video/out/x11_icon.bin",
+ target = "video/out/x11_icon.inc")
+
+ ctx.file2string(
+ source = "etc/input.conf",
+ target = "mpvcore/input/input_conf.h")
+
+ ctx.file2string(
+ source = "video/out/gl_video_shaders.glsl",
+ target = "video/out/gl_video_shaders.h")
+
+ ctx.file2string(
+ source = "sub/osd_font.otf",
+ target = "sub/osd_font.h")
+
+ ctx.file2string(
+ source = "mpvcore/player/lua/defaults.lua",
+ target = "mpvcore/player/lua/defaults.inc")
+
+ ctx.file2string(
+ source = "mpvcore/player/lua/assdraw.lua",
+ target = "mpvcore/player/lua/assdraw.inc")
+
+ ctx.file2string(
+ source = "mpvcore/player/lua/osc.lua",
+ target = "mpvcore/player/lua/osc.inc")
+
+ ctx.matroska_header(
+ source = "demux/ebml.c demux/demux_mkv.c",
+ target = "ebml_types.h")
+
+ ctx.matroska_definitions(
+ source = "demux/ebml.c",
+ target = "ebml_defs.c")
+
+ getch2_c = {
+ 'win32': 'osdep/getch2-win.c',
+ }.get(ctx.env.DEST_OS, "osdep/getch2.c")
+
+ timer_c = {
+ 'win32': 'osdep/timer-win2.c',
+ 'cygwin': 'osdep/timer-win2.c',
+ 'darwin': 'osdep/timer-darwin.c',
+ }.get(ctx.env.DEST_OS, "osdep/timer-linux.c")
+
+ sources = [
+ ## Audio
+ ( "audio/audio.c" ),
+ ( "audio/audio_buffer.c" ),
+ ( "audio/chmap.c" ),
+ ( "audio/chmap_sel.c" ),
+ ( "audio/fmt-conversion.c" ),
+ ( "audio/format.c" ),
+ ( "audio/mixer.c" ),
+ ( "audio/reorder_ch.c" ),
+ ( "audio/decode/ad_lavc.c" ),
+ ( "audio/decode/ad_mpg123.c", "mpg123" ),
+ ( "audio/decode/ad_spdif.c" ),
+ ( "audio/decode/dec_audio.c" ),
+ ( "audio/filter/af.c" ),
+ ( "audio/filter/af_bs2b.c", "libbs2b" ),
+ ( "audio/filter/af_center.c" ),
+ ( "audio/filter/af_channels.c" ),
+ ( "audio/filter/af_convert24.c" ),
+ ( "audio/filter/af_convertsignendian.c" ),
+ ( "audio/filter/af_delay.c" ),
+ ( "audio/filter/af_drc.c" ),
+ ( "audio/filter/af_dummy.c" ),
+ ( "audio/filter/af_equalizer.c" ),
+ ( "audio/filter/af_export.c", "sys-mman-h" ),
+ ( "audio/filter/af_extrastereo.c" ),
+ ( "audio/filter/af_format.c" ),
+ ( "audio/filter/af_hrtf.c" ),
+ ( "audio/filter/af_karaoke.c" ),
+ ( "audio/filter/af_ladspa.c", "ladspa" ),
+ ( "audio/filter/af_lavcac3enc.c" ),
+ ( "audio/filter/af_lavfi.c", "af-lavfi" ),
+ ( "audio/filter/af_lavrresample.c" ),
+ ( "audio/filter/af_pan.c" ),
+ ( "audio/filter/af_scaletempo.c" ),
+ ( "audio/filter/af_sinesuppress.c" ),
+ ( "audio/filter/af_sub.c" ),
+ ( "audio/filter/af_surround.c" ),
+ ( "audio/filter/af_sweep.c" ),
+ ( "audio/filter/af_volume.c" ),
+ ( "audio/filter/filter.c" ),
+ ( "audio/filter/tools.c" ),
+ ( "audio/filter/window.c" ),
+ ( "audio/out/ao.c" ),
+ ( "audio/out/ao_alsa.c", "alsa" ),
+ ( "audio/out/ao_coreaudio.c", "coreaudio" ),
+ ( "audio/out/ao_coreaudio_properties.c", "coreaudio" ),
+ ( "audio/out/ao_coreaudio_utils.c", "coreaudio" ),
+ ( "audio/out/ao_dsound.c", "dsound" ),
+ ( "audio/out/ao_jack.c", "jack" ),
+ ( "audio/out/ao_lavc.c", "encoding" ),
+ ( "audio/out/ao_null.c" ),
+ ( "audio/out/ao_openal.c", "openal" ),
+ ( "audio/out/ao_oss.c", "oss-audio" ),
+ ( "audio/out/ao_pcm.c" ),
+ ( "audio/out/ao_portaudio.c", "portaudio" ),
+ ( "audio/out/ao_pulse.c", "pulse" ),
+ ( "audio/out/ao_rsound.c", "rsound" ),
+ ( "audio/out/ao_sdl.c", "sdl" ),
+ ( "audio/out/ao_sdl.c", "sdl2" ),
+ ( "audio/out/ao_sndio.c", "sndio" ),
+ ( "audio/out/ao_wasapi.c", "wasapi" ),
+
+ ## Core
+ ( "mpvcore/input/input.c" ),
+ ( "mpvcore/input/joystick.c", "joystick" ),
+ ( "mpvcore/input/lirc.c", "lirc" ),
+ ( "mpvcore/player/audio.c" ),
+ ( "mpvcore/player/command.c" ),
+ ( "mpvcore/player/configfiles.c" ),
+ ( "mpvcore/player/loadfile.c" ),
+ ( "mpvcore/player/main.c" ),
+ ( "mpvcore/player/misc.c" ),
+ ( "mpvcore/player/mp_lua.c", "lua" ),
+ ( "mpvcore/player/osd.c" ),
+ ( "mpvcore/player/playloop.c" ),
+ ( "mpvcore/player/screenshot.c" ),
+ ( "mpvcore/player/sub.c" ),
+ ( "mpvcore/player/timeline/tl_cue.c" ),
+ ( "mpvcore/player/timeline/tl_mpv_edl.c" ),
+ ( "mpvcore/player/timeline/tl_matroska.c" ),
+ ( "mpvcore/player/video.c" ),
+ ( "mpvcore/asxparser.c" ),
+ ( "mpvcore/av_common.c" ),
+ ( "mpvcore/av_log.c" ),
+ ( "mpvcore/av_opts.c" ),
+ ( "mpvcore/bstr.c" ),
+ ( "mpvcore/charset_conv.c" ),
+ ( "mpvcore/codecs.c" ),
+ ( "mpvcore/cpudetect.c" ),
+ ( "mpvcore/encode_lavc.c", "encoding" ),
+ ( "mpvcore/m_config.c" ),
+ ( "mpvcore/m_option.c" ),
+ ( "mpvcore/m_property.c" ),
+ ( "mpvcore/mp_common.c" ),
+ ( "mpvcore/mp_msg.c" ),
+ ( "mpvcore/mp_ring.c" ),
+ ( "mpvcore/options.c" ),
+ ( "mpvcore/parser-cfg.c" ),
+ ( "mpvcore/parser-mpcmd.c" ),
+ ( "mpvcore/path.c" ),
+ ( "mpvcore/playlist.c" ),
+ ( "mpvcore/playlist_parser.c" ),
+ ( "mpvcore/resolve_quvi.c", "libquvi4" ),
+ ( "mpvcore/resolve_quvi9.c", "libquvi9" ),
+ ( "mpvcore/version.c" ),
+
+ ## Demuxers
+ ( "demux/codec_tags.c" ),
+ ( "demux/demux.c" ),
+ ( "demux/demux_cue.c" ),
+ ( "demux/demux_edl.c" ),
+ ( "demux/demux_lavf.c" ),
+ ( "demux/demux_libass.c", "libass"),
+ ( "demux/demux_mf.c" ),
+ ( "demux/demux_mkv.c" ),
+ ( "demux/demux_playlist.c" ),
+ ( "demux/demux_raw.c" ),
+ ( "demux/demux_subreader.c" ),
+ ( "demux/ebml.c" ),
+ ( "demux/mf.c" ),
+
+ ## Streams
+ ( "stream/ai_alsa1x.c", "alsa" ),
+ ( "stream/ai_oss.c", "oss-audio" ),
+ ( "stream/ai_sndio.c", "sndio" ),
+ ( "stream/audio_in.c", "audio-input" ),
+ ( "stream/cache.c", "stream-cache"),
+ ( "stream/cdinfo.c", "cdda"),
+ ( "stream/cookies.c" ),
+ ( "stream/dvb_tune.c", "dvbin" ),
+ ( "stream/frequencies.c", "tv" ),
+ ( "stream/rar.c" ),
+ ( "stream/stream.c" ),
+ ( "stream/stream_avdevice.c" ),
+ ( "stream/stream_bluray.c", "libbluray" ),
+ ( "stream/stream_cdda.c", "cdda" ),
+ ( "stream/stream_dvb.c", "dvbin" ),
+ ( "stream/stream_dvd.c", "dvdread" ),
+ ( "stream/stream_dvd_common.c", "dvdread" ),
+ ( "stream/stream_edl.c" ),
+ ( "stream/stream_file.c" ),
+ ( "stream/stream_lavf.c" ),
+ ( "stream/stream_memory.c" ),
+ ( "stream/stream_mf.c" ),
+ ( "stream/stream_null.c" ),
+ ( "stream/stream_pvr.c", "pvr" ),
+ ( "stream/stream_radio.c", "radio" ),
+ ( "stream/stream_rar.c" ),
+ ( "stream/stream_smb.c", "libsmbclient" ),
+ ( "stream/stream_tv.c", "tv" ),
+ ( "stream/stream_vcd.c", "vcd" ),
+ ( "stream/tv.c", "tv" ),
+ ( "stream/tvi_dummy.c", "tv" ),
+ ( "stream/tvi_v4l2.c", "tv-v4l2"),
+
+ ## Subtitles
+ ( "sub/ass_mp.c", "libass"),
+ ( "sub/dec_sub.c" ),
+ ( "sub/draw_bmp.c" ),
+ ( "sub/find_subfiles.c" ),
+ ( "sub/img_convert.c" ),
+ ( "sub/osd_dummy.c", "dummy-osd" ),
+ ( "sub/osd_libass.c", "libass-osd" ),
+ ( "sub/sd_ass.c", "libass" ),
+ ( "sub/sd_lavc.c" ),
+ ( "sub/sd_lavc_conv.c" ),
+ ( "sub/sd_lavf_srt.c" ),
+ ( "sub/sd_microdvd.c" ),
+ ( "sub/sd_movtext.c" ),
+ ( "sub/sd_spu.c" ),
+ ( "sub/sd_srt.c" ),
+ ( "sub/spudec.c" ),
+ ( "sub/sub.c" ),
+
+ ## Video
+ ( "video/csputils.c" ),
+ ( "video/fmt-conversion.c" ),
+ ( "video/image_writer.c" ),
+ ( "video/img_format.c" ),
+ ( "video/mp_image.c" ),
+ ( "video/mp_image_pool.c" ),
+ ( "video/sws_utils.c" ),
+ ( "video/vaapi.c", "vaapi" ),
+ ( "video/vdpau.c", "vdpau" ),
+ ( "video/decode/dec_video.c"),
+ ( "video/decode/lavc_dr1.c", "!avutil-refcounting" ),
+ ( "video/decode/vaapi.c", "vaapi-hwaccel" ),
+ ( "video/decode/vd.c" ),
+ ( "video/decode/vd_lavc.c" ),
+ ( "video/decode/vda.c", "vda-hwaccel" ),
+ ( "video/decode/vdpau.c", "vdpau-hwaccel" ),
+ ( "video/decode/vdpau_old.c", "vdpau-decoder" ),
+ ( "video/filter/pullup.c" ),
+ ( "video/filter/vf.c" ),
+ ( "video/filter/vf_crop.c" ),
+ ( "video/filter/vf_delogo.c" ),
+ ( "video/filter/vf_divtc.c" ),
+ ( "video/filter/vf_dlopen.c", "dlopen" ),
+ ( "video/filter/vf_down3dright.c" ),
+ ( "video/filter/vf_dsize.c" ),
+ ( "video/filter/vf_eq.c" ),
+ ( "video/filter/vf_expand.c" ),
+ ( "video/filter/vf_flip.c" ),
+ ( "video/filter/vf_format.c" ),
+ ( "video/filter/vf_gradfun.c" ),
+ ( "video/filter/vf_hqdn3d.c" ),
+ ( "video/filter/vf_ilpack.c" ),
+ ( "video/filter/vf_lavfi.c", "vf-lavfi"),
+ ( "video/filter/vf_mirror.c" ),
+ ( "video/filter/vf_noformat.c" ),
+ ( "video/filter/vf_noise.c" ),
+ ( "video/filter/vf_phase.c" ),
+ ( "video/filter/vf_pp.c", "libpostproc" ),
+ ( "video/filter/vf_pullup.c" ),
+ ( "video/filter/vf_rotate.c" ),
+ ( "video/filter/vf_scale.c" ),
+ ( "video/filter/vf_screenshot.c" ),
+ ( "video/filter/vf_softpulldown.c" ),
+ ( "video/filter/vf_stereo3d.c" ),
+ ( "video/filter/vf_sub.c" ),
+ ( "video/filter/vf_swapuv.c" ),
+ ( "video/filter/vf_unsharp.c" ),
+ ( "video/filter/vf_vavpp.c", "vaapi-vpp"),
+ ( "video/filter/vf_vo.c" ),
+ ( "video/filter/vf_yadif.c" ),
+ ( "video/out/aspect.c" ),
+ ( "video/out/bitmap_packer.c" ),
+ ( "video/out/cocoa/additions.m", "cocoa" ),
+ ( "video/out/cocoa/view.m", "cocoa" ),
+ ( "video/out/cocoa/window.m", "cocoa" ),
+ ( "video/out/cocoa_common.m", "cocoa" ),
+ ( "video/out/dither.c" ),
+ ( "video/out/filter_kernels.c" ),
+ ( "video/out/gl_cocoa.c", "gl-cocoa" ),
+ ( "video/out/gl_common.c", "gl" ),
+ ( "video/out/gl_hwdec_vaglx.c", "vaapi-glx" ),
+ ( "video/out/gl_hwdec_vdpau.c", "vdpau-gl-x11" ),
+ ( "video/out/gl_lcms.c", "gl" ),
+ ( "video/out/gl_osd.c", "gl" ),
+ ( "video/out/gl_video.c", "gl" ),
+ ( "video/out/gl_w32.c", "gl-win32" ),
+ ( "video/out/gl_wayland.c", "gl-wayland" ),
+ ( "video/out/gl_x11.c", "gl-x11" ),
+ ( "video/out/pnm_loader.c", "gl" ),
+ ( "video/out/vo.c" ),
+ ( "video/out/vo_caca.c", "caca" ),
+ ( "video/out/vo_corevideo.c", "corevideo"),
+ ( "video/out/vo_direct3d.c", "direct3d" ),
+ ( "video/out/vo_image.c" ),
+ ( "video/out/vo_lavc.c", "encoding" ),
+ ( "video/out/vo_null.c" ),
+ ( "video/out/vo_opengl.c", "gl" ),
+ ( "video/out/vo_opengl_old.c", "gl" ),
+ ( "video/out/vo_sdl.c", "sdl2" ),
+ ( "video/out/vo_vaapi.c", "vaapi" ),
+ ( "video/out/vo_vdpau.c", "vdpau" ),
+ ( "video/out/vo_wayland.c", "wayland" ),
+ ( "video/out/vo_x11.c" , "x11" ),
+ ( "video/out/vo_xv.c", "xv" ),
+ ( "video/out/w32_common.c", "os-win32" ),
+ ( "video/out/w32_common.c", "os-cygwin" ),
+ ( "video/out/wayland_common.c", "wayland" ),
+ ( "video/out/x11_common.c", "x11" ),
+
+ ## osdep
+ ( getch2_c ),
+ ( "osdep/io.c" ),
+ ( "osdep/numcores.c"),
+ ( "osdep/timer.c" ),
+ ( timer_c ),
+ ( "osdep/threads.c" ),
+
+ ( "osdep/ar/HIDRemote.m", "cocoa" ),
+ ( "osdep/macosx_application.m", "cocoa" ),
+ ( "osdep/macosx_events.m", "cocoa" ),
+ ( "osdep/path-macosx.m", "cocoa" ),
+
+ ( "osdep/path-win.c", "os-win32" ),
+ ( "osdep/path-win.c", "os-cygwin" ),
+ ( "osdep/glob-win.c", "glob-win32-replacement" ),
+ ( "osdep/priority.c", "priority" ),
+ ( "osdep/mpv.rc", "win32-executable" ),
+
+ ## tree_allocator
+ "ta/ta.c", "ta/ta_talloc.c", "ta/ta_utils.c"
+ ]
+
+ if ctx.dependency_satisfied('win32-executable'):
+ from waflib import TaskGen
+
+ TaskGen.declare_chain(
+ name = 'windres',
+ rule = '${WINDRES} ${WINDRES_FLAGS} ${SRC} ${TGT}',
+ ext_in = '.rc',
+ ext_out = '-rc.o',
+ color = 'PINK')
+
+ ctx.env.WINDRES_FLAGS = [
+ '--include-dir={0}'.format(ctx.bldnode.abspath()),
+ '--include-dir={0}'.format(ctx.srcnode.abspath())
+ ]
+
+ for node in 'osdep/mpv.exe.manifest etc/mpv-icon.ico'.split():
+ ctx.add_manual_dependency(
+ ctx.path.find_node('osdep/mpv.rc'),
+ ctx.path.find_node(node))
+
+ cprog_kwargs = {}
+ if ctx.dependency_satisfied('macosx-bundle'):
+ import os
+ basepath = 'TOOLS/osxbundle/mpv.app/Contents'
+ cprog_kwargs['mac_app'] = True
+ cprog_kwargs['mac_plist'] = os.path.join(basepath, 'Info.plist')
+
+ resources_glob = os.path.join(basepath, 'Resources', '*')
+ resources_nodes = ctx.srcnode.ant_glob(resources_glob)
+ resources = [node.srcpath() for node in resources_nodes]
+ cprog_kwargs['mac_resources'] = resources
+
+ ctx(
+ target = "mpv",
+ source = ctx.filtered_sources(sources),
+ use = ctx.dependencies_use(),
+ includes = [ctx.bldnode.abspath(), ctx.srcnode.abspath()] + \
+ ctx.dependencies_includes(),
+ features = "c cprogram",
+ install_path = ctx.env.BINDIR,
+ **cprog_kwargs
+ )
+
+ if ctx.dependency_satisfied("vf-dlopen-filters"):
+ dlfilters = "showqscale telecine tile rectangle framestep \
+ ildetect".split()
+ for dlfilter in dlfilters:
+ ctx(
+ target = dlfilter,
+ source = ['TOOLS/vf_dlopen/'+dlfilter+'.c',
+ 'TOOLS/vf_dlopen/filterutils.c'],
+ includes = [ctx.srcnode.abspath() + '/video/filter'],
+ features = 'c cshlib',
+ install_path = ctx.env.LIBDIR + '/mpv' )
+
+ if ctx.dependency_satisfied('manpage-build'):
+ _build_man(ctx)
+
+ if ctx.dependency_satisfied('pdf-build'):
+ _build_pdf(ctx)
+
+ ctx.install_files(
+ ctx.env.DATADIR + '/applications',
+ ['etc/mpv.desktop'] )
+
+ for size in '16x16 32x32 64x64'.split():
+ ctx.install_as(
+ ctx.env.DATADIR + '/icons/hicolor/' + size + '/apps/mpv.png',
+ 'etc/mpv-icon-8bit-' + size + '.png')