# vi: ft=python import sys, os, re sys.path.insert(0, os.path.join(os.getcwd(), 'waftools')) sys.path.insert(0, os.getcwd()) from shlex import split from waflib.Configure import conf from waflib.Tools import c_preproc from waflib.Tools.compiler_c import c_compiler from waflib import Utils from waftools.checks.generic import * from waftools.checks.custom import * c_preproc.go_absolute=True # enable system folders c_preproc.standard_includes.append('/usr/local/include') c_compiler['win32'].remove('msvc') APPNAME = 'mpv' """ Dependency identifiers (for win32 vs. Unix): wscript / C source meaning -------------------------------------------------------------------------- posix / HAVE_POSIX: defined on Linux, OSX, Cygwin (Cygwin emulates POSIX APIs on Windows) mingw / __MINGW32__: defined if posix is not defined (Windows without Cygwin) os-win32 / _WIN32: defined if basic windows.h API is available win32-desktop / HAVE_WIN32_DESKTOP: defined if desktop windows.h API is available uwp / HAVE_UWP: defined if building for UWP (basic Windows only) """ build_options = [ { 'name': '--lgpl', 'desc': 'LGPL (version 2.1 or later) build', 'default': 'disable', 'func': check_true, }, { 'name': 'gpl', 'desc': 'GPL (version 2 or later) build', 'deps': '!lgpl', 'func': check_true, }, { 'name': '--cplayer', 'desc': 'mpv CLI player', 'default': 'enable', 'func': check_true }, { 'name': '--libmpv-shared', 'desc': 'shared library', 'default': 'disable', 'func': check_true }, { 'name': '--libmpv-static', 'desc': 'static library', 'default': 'disable', 'deps': '!libmpv-shared', 'func': check_true }, { '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': '--optimize', 'desc': 'whether to optimize', 'default': 'enable', 'func': check_true }, { 'name': '--debug-build', 'desc': 'whether to compile-in debugging information', 'default': 'enable', 'func': check_true }, { 'name': '--tests', 'desc': 'unit tests (development only)', 'default': 'disable', 'func': check_true }, { # Reminder: normally always built, but enabled by MPV_LEAK_REPORT. # Building it can be disabled only by defining NDEBUG through CFLAGS. 'name': '--ta-leak-report', 'desc': 'enable ta leak report by default (development only)', 'default': 'disable', 'func': check_true }, { 'name': '--manpage-build', 'desc': 'manpage generation', 'func': check_ctx_vars('RST2MAN') }, { 'name': '--html-build', 'desc': 'html manual generation', 'func': check_ctx_vars('RST2HTML'), 'default': 'disable', }, { 'name': '--pdf-build', 'desc': 'pdf manual generation', 'func': check_ctx_vars('RST2PDF'), 'default': 'disable', }, { 'name': 'libdl', 'desc': 'dynamic loader', 'func': check_libs(['dl'], check_statement('dlfcn.h', 'dlopen("", 0)')) }, { 'name': '--cplugins', 'desc': 'C plugins', 'deps': 'libdl && !os-win32', 'func': check_cc(linkflags=['-rdynamic']), }, { # does nothing - left for backward and forward compatibility 'name': '--asm', 'desc': 'inline assembly (currently without effect)', 'default': 'enable', 'func': check_true, }, { 'name': '--vector', 'desc': 'GCC vector instructions', 'func': check_statement([], 'float v __attribute__((vector_size(32)))'), }, { 'name': '--clang-database', 'desc': 'generate a clang compilation database', 'func': check_true, 'default': 'disable', } , { 'name': '--swift-static', 'desc': 'static Swift linking', 'deps': 'os-darwin', 'func': check_ctx_vars('SWIFT_LIB_STATIC'), 'default': 'disable' } ] 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': 'libm', 'desc': '-lm', 'func': check_cc(lib='m') }, { 'name': 'mingw', 'desc': 'MinGW', 'deps': 'os-win32', 'func': check_statement('stdlib.h', 'int x = __MINGW32__;' 'int y = __MINGW64_VERSION_MAJOR'), }, { 'name': 'posix', 'desc': 'POSIX environment', 'func': check_statement(['unistd.h'], 'long x = _POSIX_VERSION'), }, { 'name': '--android', 'desc': 'Android environment', 'func': check_statement('android/api-level.h', '(void)__ANDROID__'), # arbitrary android-specific header }, { 'name': '--android-media-ndk', 'desc': 'Android Media APIs', 'deps': 'android', # header only, library is dynamically loaded 'func': check_statement('media/NdkImageReader.h', 'int x = AIMAGE_FORMAT_PRIVATE'), }, { 'name': '--tvos', 'desc': 'tvOS environment', 'func': check_statement( ['TargetConditionals.h', 'assert.h'], 'static_assert(TARGET_OS_TV, "TARGET_OS_TV defined to zero!")' ), }, { 'name': '--egl-android', 'desc': 'Android EGL support', 'deps': 'android', 'groups': [ 'gl' ], 'func': check_cc(lib=['android', 'EGL']), }, { 'name': 'posix-or-mingw', 'desc': 'development environment', 'deps': 'posix || mingw', 'func': check_true, 'req': True, 'fmsg': 'Unable to find either POSIX or MinGW-w64 environment, ' \ 'or compiler does not work.', }, { 'name': '--swift', 'desc': 'macOS Swift build tools', 'deps': 'os-darwin', 'func': compose_checks(check_swift('4.1'), check_macos_sdk('10.10')), }, { 'name': '--uwp', 'desc': 'Universal Windows Platform', 'default': 'disable', 'deps': 'os-win32 && mingw && !cplayer', 'func': check_cc(lib=['windowsapp']), }, { 'name': 'win32-desktop', 'desc': 'win32 desktop APIs', 'deps': '(os-win32 || os-cygwin) && !uwp', 'func': check_cc(lib=['winmm', 'gdi32', 'ole32', 'uuid', 'avrt', 'dwmapi', 'version']), }, { 'name': '--win32-internal-pthreads', 'desc': 'internal pthread wrapper for win32 (Vista+)', 'deps': 'os-win32 && !posix', 'func': check_true, }, { 'name': 'pthreads', 'desc': 'POSIX threads', 'func': check_pthreads, 'req': True, 'fmsg': 'Unable to find pthreads support.' }, { # NB: this works only if a source file includes osdep/threads.h # also, technically, triggers undefined behavior (reserved names) 'name': '--pthread-debug', 'desc': 'pthread runtime debugging wrappers', 'default': 'disable', 'func': check_cc(cflags='-DMP_PTHREAD_DEBUG'), # The win32 wrapper defines pthreads symbols as macros only. 'deps_neg': 'win32-internal-pthreads', }, { 'name': '--stdatomic', 'desc': 'C11 stdatomic.h', 'func': check_libs(['atomic'], check_statement('stdatomic.h', 'atomic_int_least64_t test = ATOMIC_VAR_INIT(123);' 'atomic_fetch_add(&test, 1)')), 'req': True, 'fmsg': 'C11 atomics are required; you may need a newer compiler', }, { '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': 'os-win32 || os-cygwin', 'func': check_true }, { 'name': 'glob-posix', 'desc': 'glob() POSIX support', 'deps': '!(os-win32 || os-cygwin)', 'func': check_statement('glob.h', 'glob("filename", 0, 0, 0)'), }, { 'name': 'glob-win32', 'desc': 'glob() win32 replacement', 'deps': '!posix && (os-win32 || os-cygwin)', 'func': check_true }, { 'name': 'glob', 'desc': 'any glob() support', 'deps': 'glob-posix || glob-win32', 'func': check_true, }, { 'name': 'vt.h', 'desc': 'vt.h', 'func': check_statement(['sys/vt.h', 'sys/ioctl.h'], 'int m; ioctl(0, VT_GETMODE, &m)'), }, { 'name': 'consio.h', 'desc': 'consio.h', 'deps': '!vt.h', 'func': check_statement(['sys/consio.h', 'sys/ioctl.h'], 'int m; ioctl(0, VT_GETMODE, &m)'), }, { 'name': 'gbm.h', 'desc': 'gbm.h', 'func': check_cc(header_name=['stdio.h', 'gbm.h']), }, { 'name': 'glibc-thread-name', 'desc': 'GLIBC API for setting thread name', 'func': check_statement('pthread.h', 'pthread_setname_np(pthread_self(), "ducks")', use=['pthreads']), }, { 'name': 'osx-thread-name', 'desc': 'OSX API for setting thread name', 'deps': '!glibc-thread-name', 'func': check_statement('pthread.h', 'pthread_setname_np("ducks")', use=['pthreads']), }, { 'name': 'bsd-thread-name', 'desc': 'BSD API for setting thread name', 'deps': '!(glibc-thread-name || osx-thread-name)', 'func': check_statement(['pthread.h', 'pthread_np.h'], 'pthread_set_name_np(pthread_self(), "ducks")', use=['pthreads']), }, { 'name': 'bsd-fstatfs', 'desc': "BSD's fstatfs()", 'func': check_statement(['sys/param.h', 'sys/mount.h'], 'struct statfs fs; fstatfs(0, &fs); fs.f_fstypename') }, { 'name': 'linux-fstatfs', 'desc': "Linux's fstatfs()", 'deps': 'os-linux', 'func': check_statement('sys/vfs.h', 'struct statfs fs; fstatfs(0, &fs); fs.f_namelen') }, { 'name': 'linux-input-event-codes', 'desc': "Linux's input-event-codes.h", 'func': check_cc(header_name=['linux/input-event-codes.h']), }, { 'name' : '--lua', 'desc' : 'Lua', 'func': check_lua, }, { 'name' : '--javascript', 'desc' : 'Javascript (MuJS backend)', 'func': check_pkg_config('mujs', '>= 1.0.0'), }, { 'name': 'libass', 'desc': 'SSA/ASS support', 'func': check_pkg_config('libass', '>= 0.12.2'), 'req': True, 'fmsg': "Unable to find development files for libass, or the version " + "found is too old. Aborting." }, { 'name': '--zlib', 'desc': 'zlib', 'func': any_check(check_pkg_config('zlib'), check_libs(['z'], check_statement('zlib.h', 'inflate(0, Z_NO_FLUSH)'))), 'req': True, 'fmsg': 'Unable to find development files for zlib.' }, { 'name': '--libbluray', 'desc': 'Bluray support', 'func': check_pkg_config('libbluray', '>= 0.3.0'), #'default': 'disable', }, { 'name': '--dvdnav', 'desc': 'dvdnav support', 'deps': 'gpl', 'func': check_pkg_config('dvdnav', '>= 4.2.0', 'dvdread', '>= 4.1.0'), 'default': 'disable', }, { 'name': '--cdda', 'desc': 'cdda support (libcdio)', 'deps': 'gpl', 'func': check_pkg_config('libcdio_paranoia'), 'default': 'disable', }, { 'name': '--uchardet', 'desc': 'uchardet support', 'deps': 'iconv', 'func': check_pkg_config('uchardet'), }, { 'name': '--rubberband', 'desc': 'librubberband support', 'func': check_pkg_config('rubberband', '>= 1.8.0'), }, { 'name': '--zimg', 'desc': 'libzimg support (high quality software scaler)', 'func': check_pkg_config('zimg', '>= 2.9'), }, { 'name': '--lcms2', 'desc': 'LCMS2 support', 'func': check_pkg_config('lcms2', '>= 2.6'), }, { 'name': '--vapoursynth', 'desc': 'VapourSynth filter bridge', 'func': check_pkg_config('vapoursynth', '>= 24', 'vapoursynth-script', '>= 23'), }, { 'name': '--libarchive', 'desc': 'libarchive wrapper for reading zip files and more', 'func': check_pkg_config('libarchive >= 3.4.0'), }, { 'name': '--dvbin', 'desc': 'DVB input module', 'deps': 'gpl', 'func': check_true, 'default': 'disable', }, { 'name': '--sdl2', 'desc': 'SDL2', 'func': check_pkg_config('sdl2'), 'default': 'disable', }, { 'name': '--sdl2-gamepad', 'desc': 'SDL2 gamepad input', 'deps': 'sdl2', 'func': check_true, }, { 'name': 'jpegxl', 'desc': 'JPEG XL support via libavcodec', 'func': check_pkg_config('libavcodec >= 59.27.100'), }, { 'name': 'rubberband-3', 'desc': 'new engine support for librubberband', 'func': check_pkg_config('rubberband >= 3.0.0'), } ] libav_dependencies = [ { 'name': 'ffmpeg', 'desc': 'FFmpeg library', 'func': check_pkg_config('libavutil', '>= 56.70.100', 'libavcodec', '>= 58.134.100', 'libavformat', '>= 58.76.100', 'libswscale', '>= 5.9.100', 'libavfilter', '>= 7.110.100', 'libswresample', '>= 3.9.100'), 'req': True, 'fmsg': "Unable to find development files for some of the required \ FFmpeg libraries. Git master is recommended." }, { 'name': 'av-channel-layout', 'desc': 'FFmpeg AVChannelLayout API', 'func': check_pkg_config('libavutil', '>= 57.24.100'), }, { 'name': '--libavdevice', 'desc': 'libavdevice', 'func': check_pkg_config('libavdevice', '>= 58.13.100'), } ] audio_output_features = [ { 'name': '--sdl2-audio', 'desc': 'SDL2 audio output', 'deps': 'sdl2', 'func': check_true, }, { 'name': '--oss-audio', 'desc': 'OSSv4 audio output', 'func': check_statement(['sys/soundcard.h'], 'int x = SNDCTL_DSP_SETPLAYVOL'), 'deps': 'posix && gpl', }, { 'name': '--pipewire', 'desc': 'PipeWire audio output', 'func': check_pkg_config('libpipewire-0.3', '>= 0.3.19') }, { 'name': '--sndio', 'desc': 'sndio audio input/output', 'func': check_pkg_config('sndio'), 'default': 'disable' }, { 'name': '--pulse', 'desc': 'PulseAudio audio output', 'func': check_pkg_config('libpulse', '>= 1.0') }, { 'name': '--jack', 'desc': 'JACK audio output', 'deps': 'gpl', 'func': check_pkg_config('jack'), }, { 'name': '--openal', 'desc': 'OpenAL audio output', 'func': check_pkg_config('openal', '>= 1.13'), 'default': 'disable' }, { 'name': '--opensles', 'desc': 'OpenSL ES audio output', 'func': check_statement('SLES/OpenSLES.h', 'slCreateEngine', lib="OpenSLES"), }, { 'name': '--alsa', 'desc': 'ALSA audio output', 'func': check_pkg_config('alsa', '>= 1.0.18'), }, { 'name': '--coreaudio', 'desc': 'CoreAudio audio output', 'func': check_cc( fragment=load_fragment('coreaudio.c'), framework_name=['CoreFoundation', 'CoreAudio', 'AudioUnit', 'AudioToolbox']) }, { 'name': '--audiounit', 'desc': 'AudioUnit output for iOS', 'func': check_cc( fragment=load_fragment('audiounit.c'), framework_name=['Foundation', 'AudioToolbox']) }, { 'name': '--wasapi', 'desc': 'WASAPI audio output', 'deps': 'os-win32 || os-cygwin', 'func': check_cc(fragment=load_fragment('wasapi.c')), } ] video_output_features = [ { 'name': '--sdl2-video', 'desc': 'SDL2 video output', 'deps': 'sdl2', 'deps_neg': 'cocoa', 'func': check_true, }, { 'name': '--cocoa', 'desc': 'Cocoa', 'func': check_cocoa }, { 'name': '--drm', 'desc': 'DRM', 'deps': 'vt.h || consio.h', 'func': check_pkg_config('libdrm', '>= 2.4.75'), }, { 'name': '--gbm', 'desc': 'GBM', 'deps': 'gbm.h', 'func': check_pkg_config('gbm', '>= 17.1.0'), } , { 'name': 'wayland-scanner', 'desc': 'wayland-scanner', 'func': check_program('wayland-scanner', 'WAYSCAN') } , { 'name': 'wayland-protocols', 'desc': 'wayland-protocols', 'func': check_wl_protocols } , { 'name': '--wayland', 'desc': 'Wayland', 'deps': 'wayland-protocols && wayland-scanner && linux-input-event-codes', 'func': check_pkg_config('wayland-client', '>= 1.15.0', 'wayland-cursor', '>= 1.15.0', 'xkbcommon', '>= 0.3.0'), } , { 'name': 'wayland-protocols-1-24', 'desc': 'wayland-protocols version 1.24+', 'deps': 'wayland', 'func': check_pkg_config('wayland-protocols >= 1.24'), } , { 'name': 'wayland-protocols-1-27', 'desc': 'wayland-protocols version 1.27+', 'deps': 'wayland', 'func': check_pkg_config('wayland-protocols >= 1.27'), } , { 'name': 'wayland-protocols-1-31', 'desc': 'wayland-protocols version 1.31+', 'deps': 'wayland', 'func': check_pkg_config('wayland-protocols >= 1.31'), } , { 'name': 'memfd_create', 'desc': "Linux's memfd_create()", 'deps': 'wayland', 'func': check_statement('sys/mman.h', 'memfd_create("mpv", MFD_CLOEXEC | MFD_ALLOW_SEALING)') } , { 'name': '--x11', 'desc': 'X11', 'deps': 'gpl', 'func': check_pkg_config('x11', '>= 1.0.0', 'xscrnsaver', '>= 1.0.0', 'xext', '>= 1.0.0', 'xinerama', '>= 1.0.0', 'xpresent', '>= 1.0.0', 'xrandr', '>= 1.2.0'), } , { 'name': '--xv', 'desc': 'Xv video output', 'deps': 'x11', 'func': check_pkg_config('xv'), } , { 'name': '--gl-cocoa', 'desc': 'OpenGL Cocoa Backend', 'deps': 'cocoa', 'groups': [ 'gl' ], 'func': check_statement('IOSurface/IOSurface.h', 'IOSurfaceRef surface;', framework='IOSurface', cflags=['-DGL_SILENCE_DEPRECATION']) } , { 'name': '--gl-x11', 'desc': 'OpenGL X11/GLX (deprecated/legacy)', 'deps': 'x11', 'groups': [ 'gl' ], 'func': check_libs(['GL', 'GL Xdamage'], check_cc(fragment=load_fragment('gl_x11.c'), use=['x11', 'libdl', 'pthreads'])), 'default': 'disable', }, { 'name': '--rpi', 'desc': 'Raspberry Pi support', 'func': check_egl_provider(name='brcmegl', check=any_check( check_pkg_config('brcmegl'), check_pkg_config('/opt/vc/lib/pkgconfig/brcmegl.pc') )), 'default': 'disable', } , { 'name': '--egl', 'desc': 'EGL 1.4', 'groups': [ 'gl' ], 'func': check_egl_provider('1.4') } , { 'name': '--egl-x11', 'desc': 'OpenGL X11 EGL Backend', 'deps': 'x11 && egl', 'groups': [ 'gl' ], 'func': check_true, } , { 'name': '--egl-drm', 'desc': 'OpenGL DRM EGL Backend', 'deps': 'drm && gbm && egl', 'groups': [ 'gl' ], 'func': check_true, } , { 'name': '--gl-wayland', 'desc': 'OpenGL Wayland Backend', 'deps': 'wayland && egl', 'groups': [ 'gl' ], 'func': check_pkg_config('wayland-egl', '>= 9.0.0') } , { 'name': '--gl-win32', 'desc': 'OpenGL Win32 Backend', 'deps': 'win32-desktop', 'groups': [ 'gl' ], 'func': check_statement('windows.h', 'wglCreateContext(0)', lib='opengl32') } , { 'name': '--gl-dxinterop', 'desc': 'OpenGL/DirectX Interop Backend', 'deps': 'gl-win32', 'groups': [ 'gl' ], 'func': compose_checks( check_statement(['GL/gl.h', 'GL/wglext.h'], 'int i = WGL_ACCESS_WRITE_DISCARD_NV'), check_statement('d3d9.h', 'IDirect3D9Ex *d')) } , { 'name': '--egl-angle', 'desc': 'OpenGL ANGLE headers', 'deps': 'os-win32 || os-cygwin', 'groups': [ 'gl' ], 'func': check_statement(['EGL/egl.h', 'EGL/eglext.h'], 'int x = EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE') } , { 'name': '--egl-angle-lib', 'desc': 'OpenGL Win32 ANGLE Library', 'deps': 'egl-angle', 'groups': [ 'gl' ], 'func': check_statement(['EGL/egl.h'], 'eglCreateWindowSurface(0, 0, 0, 0)', lib=['EGL', 'GLESv2', 'dxguid', 'd3d9', 'gdi32', 'stdc++']) }, { 'name': '--egl-angle-win32', 'desc': 'OpenGL Win32 ANGLE Backend', 'deps': 'egl-angle && win32-desktop', 'groups': [ 'gl' ], 'func': check_true, } , { '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': 'libdl && (x11 || wayland || egl-drm)', 'func': check_pkg_config('libva', '>= 1.1.0'), }, { 'name': '--vaapi-x11', 'desc': 'VAAPI (X11 support)', 'deps': 'vaapi && x11', 'func': check_pkg_config('libva-x11', '>= 1.1.0'), }, { 'name': '--vaapi-wayland', 'desc': 'VAAPI (Wayland support)', 'deps': 'vaapi && gl-wayland', 'func': check_pkg_config('libva-wayland', '>= 1.1.0'), }, { 'name': 'dmabuf-wayland', 'desc': 'Wayland dmabuf support', 'deps': 'wayland && memfd_create && (vaapi-wayland || drm)', 'func': check_true, }, { 'name': '--vaapi-drm', 'desc': 'VAAPI (DRM/EGL support)', 'deps': 'vaapi && egl-drm', 'func': check_pkg_config('libva-drm', '>= 1.1.0'), }, { 'name': '--vaapi-x-egl', 'desc': 'VAAPI EGL on X11', 'deps': 'vaapi-x11 && egl-x11', 'func': check_true, }, { 'name': 'vaapi-egl', 'desc': 'VAAPI EGL', 'deps': 'vaapi-x-egl || vaapi-wayland || vaapi-drm', 'func': check_true, }, { 'name': '--caca', 'desc': 'CACA', 'deps': 'gpl', 'func': check_pkg_config('caca', '>= 0.99.beta18'), }, { 'name': '--jpeg', 'desc': 'JPEG support', 'func': check_cc(header_name=['stdio.h', 'jpeglib.h'], lib='jpeg', use='libm'), }, { 'name': '--direct3d', 'desc': 'Direct3D support', 'deps': 'win32-desktop && gpl', 'func': check_cc(header_name='d3d9.h'), }, { 'name': 'shaderc-shared', 'desc': 'libshaderc SPIR-V compiler (shared library)', 'deps': '!static-build', 'groups': ['shaderc'], 'func': check_pkg_config('shaderc'), }, { 'name': 'shaderc-static', 'desc': 'libshaderc SPIR-V compiler (static library)', 'deps': '!shaderc-shared', 'groups': ['shaderc'], 'func': any_check(check_pkg_config('shaderc_combined'), check_pkg_config('shaderc_static')), }, { 'name': '--shaderc', 'desc': 'libshaderc SPIR-V compiler', 'deps': 'shaderc-shared || shaderc-static', 'func': check_true, }, { 'name': 'spirv-cross-shared', 'desc': 'SPIRV-Cross SPIR-V shader converter (shared library)', 'deps': '!static-build', 'groups': ['spirv-cross'], 'func': check_pkg_config('spirv-cross-c-shared'), }, { 'name': 'spirv-cross-static', 'desc': 'SPIRV-Cross SPIR-V shader converter (static library)', 'deps': '!spirv-cross-shared', 'groups': ['spirv-cross'], 'func': check_pkg_config('spirv-cross'), }, { 'name': '--spirv-cross', 'desc': 'SPIRV-Cross SPIR-V shader converter', 'deps': 'spirv-cross-shared || spirv-cross-static', 'func': check_true, }, { 'name': '--d3d11', 'desc': 'Direct3D 11 video output', 'deps': 'win32-desktop && shaderc && spirv-cross', 'func': check_cc(header_name=['d3d11_1.h', 'dxgi1_6.h']), } , { 'name': '--ios-gl', 'desc': 'iOS OpenGL ES hardware decoding interop support', 'func': check_statement('OpenGLES/ES3/glext.h', '(void)GL_RGB32F'), # arbitrary OpenGL ES 3.0 symbol } , { 'name': '--plain-gl', 'desc': 'OpenGL without platform-specific code (e.g. for libmpv)', 'deps': 'libmpv-shared || libmpv-static', 'func': check_true, }, { 'name': '--gl', 'desc': 'OpenGL context support', 'deps': 'gl-cocoa || gl-x11 || egl-x11 || egl-drm || ' + 'gl-win32 || gl-wayland || rpi || ' + 'plain-gl', 'func': check_true, 'req': True, 'fmsg': "No OpenGL video output found or enabled. " + "Aborting. If you really mean to compile without OpenGL " + "video outputs use --disable-gl.", }, { 'name': '--libplacebo', 'desc': 'libplacebo support', 'func': check_pkg_config('libplacebo >= 4.157.0'), }, { 'name': 'libplacebo-next', 'desc': 'libplacebo v4.202+, needed for vo_gpu_next', 'deps': 'libplacebo', 'func': check_preprocessor('libplacebo/config.h', 'PL_API_VER >= 202', use='libplacebo'), }, { 'name': '--vulkan', 'desc': 'Vulkan context support', 'deps': 'libplacebo', 'func': check_pkg_config('vulkan'), }, { 'name': 'vaapi-libplacebo', 'desc': 'VAAPI libplacebo', 'deps': 'vaapi && libplacebo', 'func': check_true, }, { 'name': 'egl-helpers', 'desc': 'EGL helper functions', 'deps': 'egl || rpi || egl-angle-win32 || egl-android', 'func': check_true }, { 'name': '--sixel', 'desc': 'Sixel', 'func': check_pkg_config('libsixel', '>= 1.5'), }, { 'name': 'dmabuf-interop-gl', 'desc': 'dmabuf GL Interop', 'deps': 'egl && drm', 'func': check_true, }, { 'name': 'dmabuf-interop-pl', 'desc': 'dmabuf libplacebo interop', 'deps': 'vaapi-libplacebo', 'func': check_true, }, { # This can be removed roughly when Debian 12 is released. 'name': 'drm-is-kms', 'desc': 'drmIsKMS() function', 'deps': 'drm', 'func': check_pkg_config('libdrm', '>= 2.4.105'), }, { 'name': 'posix-shm', 'desc': "POSIX shared memory API", 'deps': 'posix', 'func': check_statement('sys/mman.h', 'shm_open("",0,0)') } ] hwaccel_features = [ { 'name': 'videotoolbox-hwaccel', 'desc': 'libavcodec videotoolbox hwaccel', 'deps': 'gl-cocoa || ios-gl', 'func': check_true, }, { 'name': '--videotoolbox-gl', 'desc': 'Videotoolbox with OpenGL', 'deps': 'gl-cocoa && videotoolbox-hwaccel', 'func': check_true }, { 'name': '--d3d-hwaccel', 'desc': 'D3D11VA hwaccel', 'deps': 'os-win32', 'func': check_true, }, { 'name': '--d3d9-hwaccel', 'desc': 'DXVA2 hwaccel', 'deps': 'd3d-hwaccel', 'func': check_true, }, { 'name': '--gl-dxinterop-d3d9', 'desc': 'OpenGL/DirectX Interop Backend DXVA2 interop', 'deps': 'gl-dxinterop && d3d9-hwaccel', 'groups': [ 'gl' ], 'func': check_true, }, { 'name': 'ffnvcodec', 'desc': 'CUDA Headers and dynamic loader', 'func': check_pkg_config('ffnvcodec >= 8.2.15.7'), }, { 'name': '--cuda-hwaccel', 'desc': 'CUDA acceleration', 'deps': 'ffnvcodec', 'func': check_true, }, { 'name': '--cuda-interop', 'desc': 'CUDA with graphics interop', 'deps': '(gl || vulkan) && cuda-hwaccel', 'func': check_true, }, { 'name': '--rpi-mmal', 'desc': 'Raspberry Pi MMAL hwaccel', 'deps': 'rpi', 'func': any_check(check_pkg_config('mmal'), check_pkg_config('/opt/vc/lib/pkgconfig/mmal.pc')), } ] standalone_features = [ { 'name': 'win32-executable', 'desc': 'w32 executable', 'deps': 'os-win32 || !(!(os-cygwin))', 'func': check_ctx_vars('WINDRES') }, { 'name': '--macos-touchbar', 'desc': 'macOS Touch Bar support', 'deps': 'cocoa', 'func': check_cc( fragment=load_fragment('touchbar.m'), framework_name=['AppKit'], compile_filename='test-touchbar.m', linkflags='-fobjc-arc') }, { 'name': '--macos-10-11-features', 'desc': 'macOS 10.11 SDK Features', 'deps': 'cocoa', 'func': check_macos_sdk('10.11') }, { 'name': '--macos-10-12-2-features', 'desc': 'macOS 10.12.2 SDK Features', 'deps': 'cocoa', 'func': check_macos_sdk('10.12.2') }, { 'name': '--macos-10-14-features', 'desc': 'macOS 10.14 SDK Features', 'deps': 'cocoa', 'func': check_macos_sdk('10.14') },{ 'name': '--macos-media-player', 'desc': 'macOS Media Player support', 'deps': 'macos-10-12-2-features && swift', 'func': check_true }, { 'name': '--macos-cocoa-cb', 'desc': 'macOS libmpv backend', 'deps': 'cocoa && swift', 'func': check_true } ] _INSTALL_DIRS_LIST = [ ('confdir', '${SYSCONFDIR}/mpv', 'configuration files'), ('zshdir', '${DATADIR}/zsh/site-functions', 'zsh completion functions'), ('confloaddir', '${CONFDIR}', 'configuration files load directory'), ('bashdir', '${DATADIR}/bash-completion/completions', 'bash completion functions'), ] def options(opt): opt.load('compiler_c') opt.load('waf_customizations') opt.load('features') opt.load('gnu_dirs') #remove unused options from gnu_dirs opt.parser.remove_option("--sbindir") opt.parser.remove_option("--libexecdir") opt.parser.remove_option("--sharedstatedir") opt.parser.remove_option("--localstatedir") opt.parser.remove_option("--oldincludedir") opt.parser.remove_option("--infodir") opt.parser.remove_option("--localedir") opt.parser.remove_option("--dvidir") opt.parser.remove_option("--pdfdir") opt.parser.remove_option("--psdir") libdir = opt.parser.get_option('--libdir') if libdir: # Replace any mention of lib64 as we keep the default # for libdir the same as before the waf update. libdir.help = libdir.help.replace('lib64', 'lib') group = opt.get_option_group("Installation directories") 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.replace('${','').replace('}',''))) group = opt.get_option_group("build and install options") group.add_option('--variant', default = '', help = 'variant name for saving configuration and build results') opt.parse_features('build and install options', build_options) optional_features = main_dependencies + libav_dependencies opt.parse_features('optional features', 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('standalone app', standalone_features) group = opt.get_option_group("optional features") group.add_option('--lua', type = 'string', dest = 'LUA_VER', help = "select Lua package to autodetect. Choices (x is 1 or 2): luadef5x, lua5x, lua5.x, lua-5.x, luajit (luadef5x is for pkg-config name 'lua', the rest are exact pkg-config names)") group.add_option('--swift-flags', type = 'string', dest = 'SWIFT_FLAGS', help = "Optional Swift compiler flags") @conf def is_optimization(ctx): return getattr(ctx.options, 'enable_optimize') @conf def is_debug_build(ctx): return getattr(ctx.options, 'enable_debug-build') def configure(ctx): from waflib import Options ctx.resetenv(ctx.options.variant) ctx.check_waf_version(mini='1.8.4') target = os.environ.get('TARGET') (cc, pkg_config, ar, windres) = ('cc', 'pkg-config', 'ar', 'windres') if target: cc = '-'.join([target, 'gcc']) pkg_config = '-'.join([target, pkg_config]) ar = '-'.join([target, ar]) windres = '-'.join([target, windres]) ctx.find_program(cc, var='CC') ctx.find_program(pkg_config, var='PKG_CONFIG') ctx.find_program(ar, var='AR') ctx.find_program('rst2html', var='RST2HTML', mandatory=False) ctx.find_program('rst2man', var='RST2MAN', mandatory=False) ctx.find_program('rst2pdf', var='RST2PDF', mandatory=False) ctx.find_program(windres, var='WINDRES', mandatory=False) ctx.find_program('perl', var='BIN_PERL', mandatory=False) ctx.add_os_flags('LIBRARY_PATH') ctx.load('compiler_c python') ctx.load('waf_customizations') ctx.load('dependencies') ctx.load('detections.compiler_swift') ctx.load('detections.compiler') ctx.load('detections.devices') ctx.load('gnu_dirs') # if libdir is not set in command line options, # override the gnu_dirs default in order to # always have `lib/` as the library directory. if not getattr(Options.options, 'LIBDIR', None): ctx.env['LIBDIR'] = Utils.subst_vars(os.path.join('${EXEC_PREFIX}', 'lib'), ctx.env) 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) if ctx.options.LUA_VER: ctx.options.enable_lua = True ctx.parse_dependencies(build_options) ctx.parse_dependencies(main_dependencies) ctx.parse_dependencies(libav_dependencies) ctx.parse_dependencies(audio_output_features) ctx.parse_dependencies(video_output_features) ctx.parse_dependencies(hwaccel_features) if ctx.options.SWIFT_FLAGS: ctx.env.SWIFT_FLAGS.extend(split(ctx.options.SWIFT_FLAGS)) ctx.parse_dependencies(standalone_features) ctx.load('generators.headers') if not ctx.dependency_satisfied('build-date'): ctx.env.CFLAGS += ['-DNO_BUILD_TIMESTAMPS'] if ctx.dependency_satisfied('clang-database'): ctx.load('clang_compilation_database') if ctx.dependency_satisfied('cplugins'): # We need to export the libmpv symbols, since the mpv binary itself is # not linked against libmpv. The C plugin needs to be able to pick # up the libmpv symbols from the binary. We still restrict the set # of exported symbols via mpv.def. ctx.env.LINKFLAGS += ['-rdynamic'] ctx.store_dependencies_lists() from waflib import Logs Logs.error("WARNING: Building mpv with waf is deprecated and will be removed the future! It is recommended to switch to meson as soon as possible.") def __write_version__(ctx): ctx( source = 'version.py', target = 'generated/version.h', rule = '${PYTHON} ${SRC} ${TGT}', always = True) def build(ctx): if ctx.options.variant not in ctx.all_envs: from waflib import Errors raise Errors.WafError( 'The project was not configured: run "waf --variant={0} configure" first!' .format(ctx.options.variant)) ctx.unpack_dependencies_lists() ctx.add_group('versionh') ctx.add_group('sources') ctx.set_group('versionh') __write_version__(ctx) ctx.set_group('sources') ctx.load('wscript_build') def init(ctx): from waflib.Build import BuildContext, CleanContext, InstallContext, UninstallContext for y in (BuildContext, CleanContext, InstallContext, UninstallContext): class tmp(y): variant = ctx.options.variant # This is needed because waf initializes the ConfigurationContext with # an arbitrary setenv('') which would rewrite the previous configuration # cache for the default variant if the configure step finishes. # Ideally ConfigurationContext should just let us override this at class # level like the other Context subclasses do with variant from waflib.Configure import ConfigurationContext class cctx(ConfigurationContext): def resetenv(self, name): self.all_envs = {} self.setenv(name)