1
0
mirror of https://github.com/mpv-player/mpv synced 2024-12-27 09:32:40 +00:00
mpv/meson.build
llyyr f5ca11e12b meson: make libplacebo a required dependency
Make it not possible to build mpv without the latest libplacebo anymore.
This will allow for less code duplication between mpv and libplacebo,
and in the future also let us delete legacy ifdefs and track libplacebo
better.
2023-10-23 13:03:29 +02:00

1786 lines
58 KiB
Meson

project('mpv',
'c',
license: ['GPL2+', 'LGPL2.1+'],
version: files('./VERSION'),
meson_version: '>=0.62.0',
default_options: [
'buildtype=debugoptimized',
'b_lundef=false',
'c_std=c11',
'warning_level=1',
]
)
build_root = meson.project_build_root()
source_root = meson.project_source_root()
python = find_program('python3')
# ffmpeg
libavcodec = dependency('libavcodec', version: '>= 58.134.100')
libavfilter = dependency('libavfilter', version: '>= 7.110.100')
libavformat = dependency('libavformat', version: '>= 58.76.100')
libavutil = dependency('libavutil', version: '>= 56.70.100')
libswresample = dependency('libswresample', version: '>= 3.9.100')
libswscale = dependency('libswscale', version: '>= 5.9.100')
libplacebo = dependency('libplacebo', version: '>=6.338.0', fallback: ['libplacebo', 'libplacebo'],
default_options: ['default_library=static', 'demos=false'])
libass = dependency('libass', version: '>= 0.12.2')
# the dependency order of libass -> ffmpeg is necessary due to
# static linking symbol resolution between fontconfig and MinGW
dependencies = [libass,
libavcodec,
libavfilter,
libavformat,
libavutil,
libplacebo,
libswresample,
libswscale]
# Keeps track of all enabled/disabled features
features = {
'debug': get_option('debug'),
'ffmpeg': true,
'gpl': get_option('gpl'),
'jpegxl': libavformat.version().version_compare('>= 59.27.100'),
'avif-muxer': libavformat.version().version_compare('>= 59.24.100'),
'libass': true,
'threads': true,
'libplacebo': true,
}
# generic sources
sources = files(
## Audio
'audio/aframe.c',
'audio/chmap.c',
'audio/chmap_sel.c',
'audio/decode/ad_lavc.c',
'audio/decode/ad_spdif.c',
'audio/filter/af_drop.c',
'audio/filter/af_format.c',
'audio/filter/af_lavcac3enc.c',
'audio/filter/af_scaletempo.c',
'audio/filter/af_scaletempo2.c',
'audio/filter/af_scaletempo2_internals.c',
'audio/fmt-conversion.c',
'audio/format.c',
'audio/out/ao.c',
'audio/out/ao_lavc.c',
'audio/out/ao_null.c',
'audio/out/ao_pcm.c',
'audio/out/buffer.c',
## Core
'common/av_common.c',
'common/av_log.c',
'common/codecs.c',
'common/common.c',
'common/encode_lavc.c',
'common/msg.c',
'common/playlist.c',
'common/recorder.c',
'common/stats.c',
'common/tags.c',
'common/version.c',
## Demuxers
'demux/codec_tags.c',
'demux/cue.c',
'demux/cache.c',
'demux/demux.c',
'demux/demux_cue.c',
'demux/demux_disc.c',
'demux/demux_edl.c',
'demux/demux_lavf.c',
'demux/demux_mf.c',
'demux/demux_mkv.c',
'demux/demux_mkv_timeline.c',
'demux/demux_null.c',
'demux/demux_playlist.c',
'demux/demux_raw.c',
'demux/demux_timeline.c',
'demux/ebml.c',
'demux/packet.c',
'demux/timeline.c',
## Filters
'filters/f_async_queue.c',
'filters/f_autoconvert.c',
'filters/f_auto_filters.c',
'filters/f_decoder_wrapper.c',
'filters/f_demux_in.c',
'filters/f_hwtransfer.c',
'filters/f_lavfi.c',
'filters/f_output_chain.c',
'filters/f_swresample.c',
'filters/f_swscale.c',
'filters/f_utils.c',
'filters/filter.c',
'filters/frame.c',
'filters/user_filters.c',
## Input
'input/cmd.c',
'input/event.c',
'input/input.c',
'input/ipc.c',
'input/keycodes.c',
## Misc
'misc/bstr.c',
'misc/charset_conv.c',
'misc/dispatch.c',
'misc/json.c',
'misc/language.c',
'misc/natural_sort.c',
'misc/node.c',
'misc/random.c',
'misc/rendezvous.c',
'misc/thread_pool.c',
'misc/thread_tools.c',
## Options
'options/m_config_core.c',
'options/m_config_frontend.c',
'options/m_option.c',
'options/m_property.c',
'options/options.c',
'options/parse_commandline.c',
'options/parse_configfile.c',
'options/path.c',
## Player
'player/audio.c',
'player/client.c',
'player/command.c',
'player/configfiles.c',
'player/external_files.c',
'player/loadfile.c',
'player/main.c',
'player/misc.c',
'player/osd.c',
'player/playloop.c',
'player/screenshot.c',
'player/scripting.c',
'player/sub.c',
'player/video.c',
## Streams
'stream/cookies.c',
'stream/stream.c',
'stream/stream_avdevice.c',
'stream/stream_cb.c',
'stream/stream_concat.c',
'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_slice.c',
## Subtitles
'sub/ass_mp.c',
'sub/dec_sub.c',
'sub/draw_bmp.c',
'sub/filter_sdh.c',
'sub/img_convert.c',
'sub/lavc_conv.c',
'sub/osd.c',
'sub/osd_libass.c',
'sub/sd_ass.c',
'sub/sd_lavc.c',
## Video
'video/csputils.c',
'video/decode/vd_lavc.c',
'video/filter/refqueue.c',
'video/filter/vf_format.c',
'video/filter/vf_sub.c',
'video/fmt-conversion.c',
'video/hwdec.c',
'video/image_loader.c',
'video/image_writer.c',
'video/img_format.c',
'video/mp_image.c',
'video/mp_image_pool.c',
'video/out/aspect.c',
'video/out/bitmap_packer.c',
'video/out/dither.c',
'video/out/dr_helper.c',
'video/out/filter_kernels.c',
'video/out/gpu/context.c',
'video/out/gpu/error_diffusion.c',
'video/out/gpu/hwdec.c',
'video/out/gpu/lcms.c',
'video/out/gpu/libmpv_gpu.c',
'video/out/gpu/osd.c',
'video/out/gpu/ra.c',
'video/out/gpu/shader_cache.c',
'video/out/gpu/spirv.c',
'video/out/gpu/user_shaders.c',
'video/out/gpu/utils.c',
'video/out/gpu/video.c',
'video/out/gpu/video_shaders.c',
'video/out/libmpv_sw.c',
'video/out/vo.c',
'video/out/vo_gpu.c',
'video/out/vo_image.c',
'video/out/vo_lavc.c',
'video/out/vo_libmpv.c',
'video/out/vo_null.c',
'video/out/vo_tct.c',
'video/out/vo_kitty.c',
'video/out/win_state.c',
'video/repack.c',
'video/sws_utils.c',
## libplacebo
'video/out/placebo/ra_pl.c',
'video/out/placebo/utils.c',
'video/out/vo_gpu_next.c',
'video/out/gpu_next/context.c',
## osdep
'osdep/io.c',
'osdep/semaphore_osx.c',
'osdep/subprocess.c',
'osdep/threads.c',
'osdep/timer.c',
## tree_allocator
'ta/ta.c',
'ta/ta_talloc.c',
'ta/ta_utils.c'
)
# compiler stuff
cc = meson.get_compiler('c')
flags = ['-D_GNU_SOURCE', '-D_FILE_OFFSET_BITS=64']
link_flags = []
test_flags = ['-Werror=implicit-function-declaration',
'-Wempty-body',
'-Wdisabled-optimization',
'-Wstrict-prototypes',
'-Wno-format-zero-length',
'-Wno-redundant-decls',
'-Wvla',
'-Wno-format-truncation',
'-Wimplicit-fallthrough',
'-fno-math-errno']
flags += cc.get_supported_arguments(test_flags)
if cc.has_multi_arguments('-Wformat', '-Werror=format-security')
flags += ['-Wformat', '-Werror=format-security']
endif
if cc.get_id() == 'gcc'
gcc_flags = ['-Wundef', '-Wmissing-prototypes', '-Wshadow',
'-Wno-switch', '-Wparentheses', '-Wpointer-arith',
'-Wno-pointer-sign',
# GCC bug 66425
'-Wno-unused-result']
flags += gcc_flags
endif
if cc.get_id() == 'clang'
clang_flags = ['-Wno-logical-op-parentheses', '-Wno-switch',
'-Wno-tautological-compare', '-Wno-pointer-sign',
'-Wno-tautological-constant-out-of-range-compare']
flags += clang_flags
endif
darwin = host_machine.system() == 'darwin'
win32 = host_machine.system() == 'cygwin' or host_machine.system() == 'windows'
posix = not win32
features += {'darwin': darwin}
features += {'posix': posix}
features += {'dos-paths': win32, 'win32': win32}
mswin_flags = ['-D_WIN32_WINNT=0x0602', '-DUNICODE', '-DCOBJMACROS',
'-DINITGUID', '-U__STRICT_ANSI__']
if host_machine.system() == 'windows'
flags += [mswin_flags, '-D__USE_MINGW_ANSI_STDIO=1']
endif
if host_machine.system() == 'cygwin'
flags += [mswin_flags, '-mwin32']
endif
noexecstack = false
if cc.has_link_argument('-Wl,-z,noexecstack')
link_flags += '-Wl,-z,noexecstack'
noexecstack = true
endif
if cc.has_link_argument('-Wl,--nxcompat,--no-seh,--dynamicbase')
link_flags += '-Wl,--nxcompat,--no-seh,--dynamicbase'
noexecstack = true
endif
features += {'noexecstack': noexecstack}
features += {'build-date': get_option('build-date')}
if not features['build-date']
flags += '-DNO_BUILD_TIMESTAMPS'
endif
features += {'ta-leak-report': get_option('ta-leak-report')}
libdl = dependency('dl', required: false)
features += {'libdl': libdl.found()}
if features['libdl']
dependencies += libdl
endif
# C11 atomics are mandatory but linking to the library is not always required.
dependencies += cc.find_library('atomic', required: false)
cplugins = get_option('cplugins').require(
win32 or (features['libdl'] and cc.has_link_argument('-rdynamic')),
error_message: 'cplugins not supported by the os or compiler!',
)
features += {'cplugins': cplugins.allowed()}
if features['cplugins'] and not win32
link_flags += '-rdynamic'
endif
# Note: this include is only used for windows pthreads and
# must be accompanied immediately by the following flags.
# This currently works because these are the last flags set
# in the build for windows. Adding any new flags after this
# will probably break something.
includedir = []
win32_pthreads = get_option('win32-internal-pthreads').require(
win32 and not posix,
error_message: 'the os is not win32!',
)
features += {'win32-internal-pthreads': win32_pthreads.allowed()}
if features['win32-internal-pthreads']
flags += ['-isystem', '-I', '-DIN_WINPTHREAD']
includedir += include_directories('osdep/win32/include')
sources += files('osdep/win32/pthread.c')
else
# pthreads is intentionally left undefined in win32 branch to find incorrect
# uses of it immediately
pthreads = dependency('threads')
dependencies += pthreads
endif
pthread_debug = get_option('pthread-debug').require(
win32_pthreads.disabled(),
error_message: 'win32-internal-pthreads was found!',
)
features += {'pthread-debug': pthread_debug.allowed()}
if features['pthread-debug']
flags += '-DMP_PTHREAD_DEBUG'
endif
add_project_arguments(flags, language: 'c')
add_project_link_arguments(link_flags, language: ['c', 'objc'])
# osdep
cocoa = dependency('appleframeworks', modules: ['Cocoa', 'IOKit', 'QuartzCore'],
required: get_option('cocoa'))
features += {'cocoa': cocoa.found()}
if features['cocoa']
dependencies += cocoa
sources += files('osdep/apple_utils.c',
'osdep/language-apple.c',
'osdep/macosx_application.m',
'osdep/macosx_events.m',
'osdep/macosx_menubar.m',
'osdep/main-fn-cocoa.c',
'osdep/path-macosx.m',
'video/out/cocoa_common.m',
'video/out/cocoa/events_view.m',
'video/out/cocoa/video_view.m',
'video/out/cocoa/window.m')
endif
if posix
path_source = files('osdep/path-unix.c')
subprocess_source = files('osdep/subprocess-posix.c')
sources += files('input/ipc-unix.c',
'osdep/poll_wrapper.c',
'osdep/terminal-unix.c',
'sub/filter_regex.c')
endif
if posix and not features['cocoa']
sources += files('osdep/main-fn-unix.c',
'osdep/language-posix.c')
endif
if darwin
path_source = files('osdep/path-darwin.c')
timer_source = files('osdep/timer-darwin.c')
endif
if posix and not darwin
timer_source = files('osdep/timer-linux.c')
endif
features += {'ppoll': cc.has_function('ppoll', args: '-D_GNU_SOURCE',
prefix: '#include <poll.h>')}
cd_devices = {
'windows': 'D:',
'cygwin': 'D:',
'darwin': '/dev/disk1',
'freebsd': '/dev/cd0',
'openbsd': '/dev/rcd0c',
'linux': '/dev/sr0',
}
if host_machine.system() in cd_devices
cd_device = cd_devices[host_machine.system()]
else
cd_device = '/dev/cdrom'
endif
dvd_devices = {
'windows': 'D:',
'cygwin': 'D:',
'darwin': '/dev/diskN',
'freebsd': '/dev/cd0',
'openbsd': '/dev/rcd0c',
'linux': '/dev/sr0',
}
if host_machine.system() in cd_devices
dvd_device = dvd_devices[host_machine.system()]
else
dvd_device = '/dev/dvd'
endif
features += {'android': host_machine.system() == 'android'}
if features['android']
dependencies += cc.find_library('android')
sources += files('audio/out/ao_audiotrack.c',
'misc/jni.c',
'osdep/android/strnlen.c',
'video/out/android_common.c',
'video/out/vo_mediacodec_embed.c')
endif
uwp_opt = get_option('uwp').require(
not get_option('cplayer'),
error_message: 'cplayer is not false!',
)
uwp = cc.find_library('windowsapp', required: uwp_opt)
features += {'uwp': uwp.found()}
if features['uwp']
dependencies += uwp
path_source = files('osdep/path-uwp.c')
subprocess_source = []
endif
features += {'win32-executable': win32 and get_option('cplayer')}
if win32
timer_source = files('osdep/timer-win2.c')
sources += files('osdep/w32_keyboard.c',
'osdep/windows_utils.c')
endif
features += {'win32-desktop': win32 and not uwp.found()}
if features['win32-desktop']
win32_desktop_libs = [cc.find_library('avrt'),
cc.find_library('dwmapi'),
cc.find_library('gdi32'),
cc.find_library('ole32'),
cc.find_library('uuid'),
cc.find_library('uxtheme'),
cc.find_library('version'),
cc.find_library('winmm')]
dependencies += win32_desktop_libs
path_source = files('osdep/path-win.c')
subprocess_source = files('osdep/subprocess-win.c')
sources += files('input/ipc-win.c',
'osdep/language-win.c',
'osdep/main-fn-win.c',
'osdep/terminal-win.c',
'video/out/w32_common.c',
'video/out/win32/displayconfig.c',
'video/out/win32/droptarget.c')
endif
if not posix and not features['win32-desktop']
subprocess_source = files('osdep/subprocess-dummy.c')
sources += files('input/ipc-dummy.c')
endif
features += {'glob-posix': cc.has_function('glob', prefix: '#include <glob.h>')}
features += {'glob-win32': win32 and not posix}
if features['glob-win32']
sources += files('osdep/glob-win.c')
endif
features += {'glob': features['glob-posix'] or features['glob-win32']}
features += {'vt.h': cc.has_header_symbol('sys/vt.h', 'VT_GETMODE')}
features += {'consio.h': not features['vt.h'] and cc.has_header_symbol('sys/consio.h', 'VT_GETMODE')}
# macOS's pthread_setname_np is a special snowflake and differs from literally every other platform.
features += {'osx-thread-name': darwin}
features += {'glibc-thread-name': false}
if not features['osx-thread-name']
features += {'glibc-thread-name': posix and cc.has_function('pthread_setname_np', args: '-D_GNU_SOURCE',
dependencies: pthreads, prefix: '#include <pthread.h>')}
endif
features += {'bsd-thread-name': false}
if not features['osx-thread-name'] and not features['glibc-thread-name']
features += {'bsd-thread-name': posix and cc.has_function('pthread_set_name_np', dependencies: pthreads,
prefix: '#include <pthread.h>\n#include <pthread_np.h>')}
endif
features += {'bsd-fstatfs': cc.has_function('fstatfs', prefix: '#include <sys/mount.h>\n#include <sys/param.h>')}
features += {'linux-fstatfs': cc.has_function('fstatfs', prefix: '#include <sys/vfs.h>')}
vector_attribute = '''int main() {
float v __attribute__((vector_size(32)));
}
'''
vector = get_option('vector').require(
cc.compiles(vector_attribute, name: 'vector check'),
error_message: 'the compiler does not support gcc vectors!',
)
features += {'vector': vector.allowed()}
sources += path_source + subprocess_source + timer_source
# various file generations
tools_directory = join_paths(source_root, 'TOOLS')
docutils_wrapper = find_program(join_paths(tools_directory, 'docutils-wrapper.py'))
file2string = find_program(join_paths(tools_directory, 'file2string.py'))
matroska = find_program(join_paths(tools_directory, 'matroska.py'))
ebml_defs = custom_target('ebml_defs.inc',
output: 'ebml_defs.inc',
command: [matroska, '--generate-definitions', '@OUTPUT@'],
)
ebml_types = custom_target('ebml_types.h',
output: 'ebml_types.h',
command: [matroska, '--generate-header', '@OUTPUT@'],
)
sources += [ebml_defs, ebml_types]
subdir('common')
subdir('etc')
subdir('player')
subdir('sub')
if darwin
subdir(join_paths('TOOLS', 'osxbundle'))
endif
# misc dependencies
features += {'av-channel-layout': libavutil.version().version_compare('>= 57.24.100')}
if features['av-channel-layout']
sources += files('audio/chmap_avchannel.c')
endif
cdda_opt = get_option('cdda').require(
get_option('gpl'),
error_message: 'the build is not GPL!',
)
cdio = dependency('libcdio', version: '>= 0.90', required: cdda_opt)
cdda = dependency('libcdio_paranoia', required: cdda_opt)
features += {'cdda': cdda.found() and cdio.found()}
if features['cdda']
dependencies += [cdda, cdio]
sources += files('stream/stream_cdda.c')
endif
dvbin = get_option('dvbin').require(
get_option('gpl'),
error_message: 'the build is not GPL!',
)
features += {'dvbin': dvbin.allowed()}
if features['dvbin']
sources += files('stream/dvb_tune.c',
'stream/stream_dvb.c')
endif
dvdnav_opt = get_option('dvdnav').require(
get_option('gpl'),
error_message: 'the build is not GPL!',
)
dvdnav = dependency('dvdnav', version: '>= 4.2.0', required: dvdnav_opt)
dvdread = dependency('dvdread', version: '>= 4.1.0', required: dvdnav_opt)
features += {'dvdnav': dvdnav.found() and dvdread.found()}
if features['dvdnav']
dependencies += [dvdnav, dvdread]
sources += files('stream/stream_dvdnav.c')
endif
iconv = dependency('iconv', required: get_option('iconv'))
features += {'iconv': iconv.found()}
if features['iconv']
dependencies += iconv
endif
javascript = dependency('mujs', version: '>= 1.0.0', required: get_option('javascript'))
features += {'javascript': javascript.found()}
if features['javascript']
dependencies += javascript
sources += files('player/javascript.c',
'sub/filter_jsre.c')
endif
lcms2 = dependency('lcms2', version: '>= 2.6', required: get_option('lcms2'))
features += {'lcms2': lcms2.found()}
if features['lcms2']
dependencies += lcms2
endif
libarchive = dependency('libarchive', version: '>= 3.4.0', required: get_option('libarchive'))
features += {'libarchive': libarchive.found()}
if features['libarchive']
dependencies += libarchive
sources += files('demux/demux_libarchive.c',
'stream/stream_libarchive.c')
endif
libavdevice = dependency('libavdevice', version: '>= 58.13.100', required: get_option('libavdevice'))
features += {'libavdevice': libavdevice.found()}
if features['libavdevice']
dependencies += libavdevice
endif
libbluray = dependency('libbluray', version: '>= 0.3.0', required: get_option('libbluray'))
features += {'libbluray': libbluray.found()}
if features['libbluray']
dependencies += libbluray
sources += files('stream/stream_bluray.c')
endif
libm = cc.find_library('m', required: false)
features += {'libm': libm.found()}
if features['libm']
dependencies += libm
endif
librt = cc.find_library('rt', required: false)
features += {'librt': librt.found()}
if features['librt']
dependencies += librt
endif
lua = dependency('', required: false)
lua_opt = get_option('lua')
if lua_opt != 'disabled'
lua_version = [['lua', ['>=5.1.0', '<5.3.0']], # generic lua.pc
['lua52', '>= 5.2.0'],
['lua5.2', '>= 5.2.0'],
['lua-5.2', '>= 5.2.0'],
['luajit', '>= 2.0.0'],
['lua51', '>= 5.1.0'],
['lua5.1', '>= 5.1.0'],
['lua-5.1', '>= 5.1.0']]
foreach version : lua_version
if lua_opt == 'auto' or lua_opt == 'enabled'
lua = dependency(version[0], version: version[1], required: false)
if lua.found()
break
endif
elif lua_opt == version[0]
lua = dependency(version[0], version: version[1])
if lua.found()
break
endif
endif
endforeach
endif
features += {'lua': lua.found()}
lua_version = lua.name()
if features['lua']
dependencies += lua
sources += files('player/lua.c')
endif
if not features['lua'] and lua_opt == 'enabled'
error('lua enabled but no suitable lua version could be found!')
endif
rubberband = dependency('rubberband', version: '>= 1.8.0', required: get_option('rubberband'))
features += {'rubberband': rubberband.found()}
features += {'rubberband-3': rubberband.version().version_compare('>= 3.0.0')}
if features['rubberband']
dependencies += rubberband
sources += files('audio/filter/af_rubberband.c')
endif
sdl2 = dependency('sdl2', required: get_option('sdl2'))
features += {'sdl2': sdl2.found()}
if features['sdl2']
dependencies += sdl2
endif
sdl2_gamepad = get_option('sdl2-gamepad').require(
features['sdl2'],
error_message: 'sdl2 was not found!',
)
features += {'sdl2-gamepad': sdl2_gamepad.allowed()}
if features['sdl2-gamepad']
sources += files('input/sdl_gamepad.c')
endif
uchardet_opt = get_option('uchardet').require(
features['iconv'],
error_message: 'iconv was not found!',
)
uchardet = dependency('uchardet', required: uchardet_opt)
features += {'uchardet': uchardet.found()}
if features['uchardet']
dependencies += uchardet
endif
features += {'lavu-uuid': libavutil.version().version_compare('>= 57.27.100')}
if not features['lavu-uuid']
sources += files('misc/uuid.c')
endif
vapoursynth = dependency('vapoursynth', version: '>= 26', required: get_option('vapoursynth'))
vapoursynth_script = dependency('vapoursynth-script', version: '>= 26',
required: get_option('vapoursynth'))
features += {'vapoursynth': vapoursynth.found() and vapoursynth_script.found()}
if features['vapoursynth']
dependencies += [vapoursynth, vapoursynth_script]
sources += files('video/filter/vf_vapoursynth.c')
endif
zimg = dependency('zimg', version: '>= 2.9', required: get_option('zimg'))
features += {'zimg': zimg.found()}
if features['zimg']
dependencies += zimg
sources += files('video/filter/vf_fingerprint.c',
'video/zimg.c')
features += {'zimg-st428': zimg.version().version_compare('>= 3.0.5')}
endif
zlib = dependency('zlib', required: get_option('zlib'))
features += {'zlib': zlib.found()}
if features['zlib']
dependencies += zlib
endif
# audio output dependencies
alsa = dependency('alsa', version: '>= 1.0.18', required: get_option('alsa'))
features += {'alsa': alsa.found()}
if features['alsa']
dependencies += alsa
sources += files('audio/out/ao_alsa.c')
endif
audiounit = {
'deps': dependency('appleframeworks', modules: ['Foundation', 'AudioToolbox'],
required: get_option('audiounit')),
'symbol': cc.has_header_symbol('AudioToolbox/AudioToolbox.h', 'kAudioUnitSubType_RemoteIO',
required: get_option('audiounit')),
}
features += {'audiounit': audiounit['deps'].found() and audiounit['symbol']}
if features['audiounit']
dependencies += audiounit['deps']
sources += files('audio/out/ao_audiounit.m')
endif
coreaudio = dependency('appleframeworks', modules: ['CoreFoundation', 'CoreAudio',
'AudioUnit', 'AudioToolbox'], required: get_option('coreaudio'))
features += {'coreaudio': coreaudio.found()}
if features['coreaudio']
dependencies += coreaudio
sources += files('audio/out/ao_coreaudio.c',
'audio/out/ao_coreaudio_exclusive.c',
'audio/out/ao_coreaudio_properties.c')
endif
if features['audiounit'] or features['coreaudio']
sources += files('audio/out/ao_coreaudio_chmap.c',
'audio/out/ao_coreaudio_utils.c')
endif
jack_opt = get_option('jack').require(
get_option('gpl'),
error_message: 'the build is not GPL!',
)
jack = dependency('jack', required: jack_opt)
features += {'jack': jack.found()}
if features['jack']
dependencies += jack
sources += files('audio/out/ao_jack.c')
endif
openal = dependency('openal', version: '>= 1.13', required: get_option('openal'))
features += {'openal': openal.found()}
if features['openal']
dependencies += openal
sources += files('audio/out/ao_openal.c')
endif
opensles = cc.find_library('OpenSLES', required: get_option('opensles'))
features += {'opensles': opensles.found()}
if features['opensles']
dependencies += opensles
sources += files('audio/out/ao_opensles.c')
endif
oss_opt = get_option('oss-audio').require(
get_option('gpl'),
error_message: 'the build is not GPL!',
)
features += {'oss-audio': cc.has_header_symbol('sys/soundcard.h', 'SNDCTL_DSP_HALT',
required: oss_opt)}
if features['oss-audio']
sources += files('audio/out/ao_oss.c')
endif
pipewire = dependency('libpipewire-0.3', version: '>= 0.3.48', required: get_option('pipewire'))
features += {'pipewire': pipewire.found()}
if features['pipewire']
dependencies += pipewire
sources += files('audio/out/ao_pipewire.c')
endif
pulse = dependency('libpulse', version: '>= 1.0', required: get_option('pulse'))
features += {'pulse': pulse.found()}
if features['pulse']
dependencies += pulse
sources += files('audio/out/ao_pulse.c')
endif
sdl2_audio = get_option('sdl2-audio').require(
features['sdl2'],
error_message: 'sdl2 was not found!',
)
features += {'sdl2-audio': sdl2_audio.allowed()}
if features['sdl2-audio']
sources += files('audio/out/ao_sdl.c')
endif
sndio = dependency('sndio', required: get_option('sndio'))
features += {'sndio': sndio.found()}
features += {'sndio-1-9': sndio.version().version_compare('>= 1.9.0')}
if features['sndio']
dependencies += sndio
sources += files('audio/out/ao_sndio.c')
endif
wasapi = cc.has_header_symbol('audioclient.h', 'IAudioClient', required: get_option('wasapi'))
features += {'wasapi': wasapi}
if features['wasapi']
sources += files('audio/out/ao_wasapi.c',
'audio/out/ao_wasapi_changenotify.c',
'audio/out/ao_wasapi_utils.c')
endif
# video output dependencies
caca_opt = get_option('caca').require(
get_option('gpl'),
error_message: 'the build is not GPL!',
)
caca = dependency('caca', version: '>= 0.99.beta18', required: caca_opt)
features += {'caca': caca.found()}
if features['caca']
dependencies += caca
sources += files('video/out/vo_caca.c')
endif
direct3d_opt = get_option('direct3d').require(
get_option('gpl') and features['win32-desktop'],
error_message: 'the build is not GPL or this is not a win32 desktop!',
)
direct3d = cc.has_header('d3d9.h', required: direct3d_opt)
features += {'direct3d': direct3d}
if features['direct3d']
sources += files('video/out/vo_direct3d.c')
endif
drm = dependency('libdrm', version: '>= 2.4.105', required: get_option('drm'))
features += {'drm': drm.found() and (features['vt.h'] or features['consio.h'])}
if features['drm']
dependencies += drm
sources += files('video/drmprime.c',
'video/out/drm_atomic.c',
'video/out/drm_common.c',
'video/out/drm_prime.c',
'video/out/hwdec/hwdec_drmprime.c',
'video/out/hwdec/hwdec_drmprime_overlay.c',
'video/out/vo_drm.c')
endif
gbm = dependency('gbm', version: '>=17.1.0', required: get_option('gbm'))
features += {'gbm': gbm.found()}
if features['gbm']
dependencies += gbm
endif
jpeg = dependency('libjpeg', required: get_option('jpeg'))
features += {'jpeg': jpeg.found()}
if features['jpeg']
dependencies += jpeg
endif
sdl2_video = get_option('sdl2-video').require(
features['sdl2'],
error_message: 'sdl2 was not found!',
)
features += {'sdl2-video': sdl2_video.allowed()}
if features['sdl2-video']
sources += files('video/out/vo_sdl.c')
endif
shaderc = dependency('shaderc', required: get_option('shaderc'))
features += {'shaderc': shaderc.found()}
if features['shaderc']
dependencies += shaderc
sources += files('video/out/gpu/spirv_shaderc.c')
endif
sixel = dependency('libsixel', version: '>= 1.5', required: get_option('sixel'))
features += {'sixel': sixel.found()}
if features['sixel']
dependencies += sixel
sources += files('video/out/vo_sixel.c')
endif
features += {'posix-shm': false}
if features['posix']
features += {'posix-shm': cc.has_function('shm_open', prefix: '#include <sys/mman.h>')}
endif
spirv_cross = dependency('spirv-cross-c-shared', required: get_option('spirv-cross'))
features += {'spirv-cross': spirv_cross.found()}
if features['spirv-cross']
dependencies += spirv_cross
endif
d3d11 = get_option('d3d11').require(
features['win32-desktop'] and features['shaderc'] and features['spirv-cross'],
error_message: 'Either is not a win32 desktop or shaderc nor spirv-cross were found!',
)
features += {'d3d11': d3d11.allowed()}
if features['d3d11']
sources += files('video/out/d3d11/context.c',
'video/out/d3d11/ra_d3d11.c')
endif
wayland = {
'deps': [dependency('wayland-client', version: '>= 1.20.0', required: get_option('wayland')),
dependency('wayland-cursor', version: '>= 1.20.0', required: get_option('wayland')),
dependency('wayland-protocols', version: '>= 1.25', required: get_option('wayland')),
dependency('xkbcommon', version: '>= 0.3.0', required: get_option('wayland'))],
'header': cc.has_header('linux/input-event-codes.h', required: get_option('wayland'),
# Pass CFLAGS from a related package as a hint for non-Linux
dependencies: dependency('wayland-client', required: get_option('wayland'))),
'scanner': find_program('wayland-scanner', required: get_option('wayland')),
}
wayland_deps = true
foreach dep: wayland['deps']
if not dep.found()
wayland_deps = false
break
endif
endforeach
features += {'wayland': wayland_deps and wayland['header'] and wayland['scanner'].found()}
if features['wayland']
subdir(join_paths('video', 'out'))
endif
features += {'memfd-create': false}
if features['wayland']
features += {'memfd-create': cc.has_function('memfd_create',
prefix: '#define _GNU_SOURCE\n#include <sys/mman.h>')}
endif
if features['wayland'] and features['memfd-create']
sources += files('video/out/vo_wlshm.c')
endif
dmabuf_wayland = get_option('dmabuf-wayland').require(
features['drm'] and features['memfd-create'] and features['wayland'],
error_message: 'drm, memfd-create or wayland was not found!',
)
features += {'dmabuf-wayland': dmabuf_wayland.allowed()}
if features['dmabuf-wayland']
sources += files('video/out/vo_dmabuf_wayland.c')
sources += files('video/out/hwdec/dmabuf_interop_wl.c')
sources += files('video/out/wldmabuf/context_wldmabuf.c')
sources += files('video/out/wldmabuf/ra_wldmabuf.c')
endif
x11_opt = get_option('x11').require(
get_option('gpl'),
error_message: 'the build is not GPL!',
)
x11 = {
'deps': [dependency('x11', version: '>= 1.0.0', required: x11_opt),
dependency('xscrnsaver', version: '>= 1.0.0', required: x11_opt),
dependency('xext', version: '>= 1.0.0', required: x11_opt),
dependency('xpresent', version: '>= 1.0.0', required: x11_opt),
dependency('xrandr', version: '>= 1.4.0', required: x11_opt)],
}
x11_deps = true
foreach dep: x11['deps']
if not dep.found()
x11_deps = false
break
endif
endforeach
features += {'x11': x11_deps}
if features['x11']
dependencies += x11['deps']
sources += files('video/out/vo_x11.c',
'video/out/x11_common.c')
endif
xv_opt = get_option('xv').require(
features['x11'],
error_message: 'x11 could not be found!',
)
xv = dependency('xv', required: xv_opt)
features += {'xv': xv.found()}
if features['xv']
dependencies += xv
sources += files('video/out/vo_xv.c')
endif
if features['wayland'] or features['x11']
sources += ('video/out/present_sync.c')
endif
# OpenGL feature checking
gl_allowed = get_option('gl').allowed()
features += {'gl': false}
GL = dependency('', required: false)
if darwin
GL = dependency('appleframeworks', modules: 'OpenGL', required: get_option('gl-cocoa'))
elif features['win32-desktop']
GL = dependency('GL', required: get_option('gl-win32'))
elif features['x11']
GL = dependency('GL', required: get_option('gl-x11'))
endif
gl_cocoa = get_option('gl-cocoa').require(
features['cocoa'] and GL.found() and gl_allowed,
error_message: 'cocoa and GL were not found!',
)
features += {'gl-cocoa': gl_cocoa.allowed()}
if features['gl-cocoa']
dependencies += GL
features += {'gl': true}
sources += files('video/out/opengl/context_cocoa.c')
endif
gl_win32 = get_option('gl-win32').require(
GL.found() and gl_allowed and features['win32-desktop'],
error_message: 'GL and win32 desktop were not found!',
)
features += {'gl-win32': gl_win32.allowed()}
if features['gl-win32']
dependencies += GL
features += {'gl': true}
sources += files('video/out/opengl/context_win.c')
endif
gl_x11 = get_option('gl-x11').require(
GL.found() and gl_allowed and features['x11'],
error_message: 'GL and x11 were not found!',
)
features += {'gl-x11': gl_x11.allowed()}
if features['gl-x11']
dependencies += GL
features += {'gl': true}
sources += files('video/out/opengl/context_glx.c')
endif
gl_dxinterop_d3d = gl_win32.allowed() and \
cc.has_header_symbol('GL/wglext.h', 'WGL_ACCESS_READ_ONLY_NV',
prefix: '#include <GL/gl.h>')
gl_dxinterop_gl = features['gl-win32'] and cc.has_header_symbol('d3d9.h', 'IDirect3D9Ex')
gl_dxinterop = get_option('gl-dxinterop').require(
gl_dxinterop_d3d and gl_dxinterop_gl and gl_win32.allowed(),
error_message: 'gl-dxinterop could not be found!',
)
features += {'gl-dxinterop': gl_dxinterop.allowed()}
if features['gl-dxinterop']
sources += files('video/out/opengl/context_dxinterop.c')
endif
egl_angle = get_option('egl-angle').require(
features['gl-win32'] and
cc.has_header_symbol('EGL/eglext.h',
'EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE',
prefix: '#include <EGL/egl.h>') and
cc.has_header_symbol('EGL/eglext_angle.h',
'PFNEGLCREATEDEVICEANGLEPROC',
# TODO: change to list when meson 1.0.0 is required
prefix: '#include <EGL/egl.h>\n#include <EGL/eglext.h>'),
error_message: 'egl-angle could not be found!',
)
features += {'egl-angle': egl_angle.allowed()}
if features['egl-angle']
sources += files('video/out/opengl/angle_dynamic.c')
endif
egl_dep = cc.find_library('EGL', required: get_option('egl-angle-lib'))
egl_angle_lib = get_option('egl-angle-lib').require(
features['egl-angle'] and cc.has_function('eglCreateWindowSurface',
dependencies: egl_dep,
prefix: '#include <EGL/egl.h>'),
error_message: 'egl-angle-lib could not be found!',
)
features += {'egl-angle-lib': egl_angle_lib.allowed()}
if features['egl-angle-lib']
dependencies += egl_dep
endif
egl_angle_win32 = get_option('egl-angle-win32').require(
features['egl-angle'] and features['win32-desktop'],
error_message: 'either this is not a win32 desktop or egl-angle was not found!',
)
features += {'egl-angle-win32': egl_angle_win32.allowed()}
if features['egl-angle-win32']
sources += files('video/out/opengl/context_angle.c')
endif
if features['d3d11'] or features['egl-angle-win32']
sources += files('video/out/gpu/d3d11_helpers.c')
endif
egl = dependency('egl', version: '> 1.4.0', required: get_option('egl'))
features += {'egl': egl.found() and gl_allowed}
if features['egl']
dependencies += egl
endif
egl_android_opt = get_option('egl-android').require(
features['android'] and gl_allowed,
error_message: 'the OS is not android!',
)
egl_android = cc.find_library('EGL', required: egl_android_opt)
features += {'egl-android': egl_android.found()}
if features['egl-android']
dependencies += egl_android
features += {'gl': true}
sources += files('video/out/opengl/context_android.c')
endif
egl_drm = get_option('egl-drm').require(
features['drm'] and features['egl'] and gbm.found() and gl_allowed,
error_message: 'either drm, egl, or gbm could not be found!',
)
features += {'egl-drm': egl_drm.allowed()}
if features['egl-drm']
features += {'gl': true}
sources += files('video/out/opengl/context_drm_egl.c')
endif
egl_wayland = dependency('wayland-egl', version: '>= 9.0.0', required: get_option('egl-wayland'))
features += {'egl-wayland': features['egl'] and egl_wayland.found() and gl_allowed and features['wayland']}
if features['egl-wayland']
dependencies += egl_wayland
features += {'gl': true}
sources += files('video/out/opengl/context_wayland.c')
endif
egl_x11 = get_option('egl-x11').require(
features['egl'] and gl_allowed and features['x11'],
error_message: 'either egl or x11 could not be found!',
)
features += {'egl-x11': egl_x11.allowed()}
if features['egl-x11']
features += {'gl': true}
sources += files('video/out/opengl/context_x11egl.c')
endif
plain_gl = get_option('plain-gl').require(
gl_allowed,
error_message: 'gl was not enabled!',
)
if plain_gl.allowed()
features += {'gl': true}
endif
rpi = dependency('/opt/vc/lib/pkgconfig/brcmegl.pc', 'brcmegl', required: get_option('rpi'))
features += {'rpi': gl_allowed and rpi.found()}
if features['rpi']
dependencies += rpi
features += {'gl': true}
sources += files('video/out/opengl/context_rpi.c')
endif
features += {'egl-helpers': features['egl'] or egl_android.found() or
egl_angle_win32.allowed() or features['rpi']}
if features['egl-helpers']
sources += files('video/out/opengl/egl_helpers.c')
endif
if features['egl'] and features['egl-helpers']
sources += files('video/filter/vf_gpu.c')
endif
if features['gl']
sources += files('video/out/opengl/common.c',
'video/out/opengl/context.c',
'video/out/opengl/formats.c',
'video/out/opengl/libmpv_gl.c',
'video/out/opengl/ra_gl.c',
'video/out/opengl/utils.c')
elif not features['gl'] and get_option('gl').enabled()
error('gl enabled but no OpenGL video output could be found!')
endif
# vulkan
vulkan_opt = get_option('vulkan').require(
libplacebo.get_variable('pl_has_vulkan', default_value: '0') == '1',
error_message: 'libplacebo compiled without vulkan support!',
)
vulkan = dependency('vulkan', version: '>= 1.1.70', required: vulkan_opt)
features += {'vulkan': vulkan.found()}
if features['vulkan']
dependencies += vulkan
sources += files('video/out/vulkan/context.c',
'video/out/vulkan/utils.c')
endif
if features['vulkan'] and features['android']
sources += files('video/out/vulkan/context_android.c')
endif
if features['vulkan'] and features['wayland']
sources += files('video/out/vulkan/context_wayland.c')
endif
if features['vulkan'] and features['win32-desktop']
sources += files('video/out/vulkan/context_win.c')
endif
if features['vulkan'] and features['x11']
sources += files('video/out/vulkan/context_xlib.c')
endif
features += {'vk-khr-display': cc.has_function('vkCreateDisplayPlaneSurfaceKHR', prefix: '#include <vulkan/vulkan_core.h>',
dependencies: [vulkan])}
if features['vk-khr-display']
sources += files('video/out/vulkan/context_display.c')
endif
# hwaccel
ffnvcodec = dependency('ffnvcodec', version: '>= 11.1.5.1', required: false)
features += {'ffnvcodec': ffnvcodec.found()}
if features['ffnvcodec']
dependencies += ffnvcodec
sources += files('video/cuda.c')
endif
android_media_ndk = get_option('android-media-ndk').require(
features['android'] and cc.has_header_symbol('media/NdkImageReader.h', 'AIMAGE_FORMAT_PRIVATE')
)
features += {'android-media-ndk': android_media_ndk.allowed()}
if features['android-media-ndk']
# header only, library is dynamically loaded
sources += files('video/out/hwdec/hwdec_aimagereader.c')
endif
cuda_hwaccel = get_option('cuda-hwaccel').require(
features['ffnvcodec'],
error_message: 'ffnvcodec was not found!',
)
features += {'cuda-hwaccel': cuda_hwaccel.allowed()}
if features['cuda-hwaccel']
sources += files('video/out/hwdec/hwdec_cuda.c')
endif
cuda_interop = get_option('cuda-interop').require(
features['cuda-hwaccel'] and (features['gl'] or features['vulkan']),
error_message: 'cuda-hwaccel and either gl or vulkan were not found!',
)
features += {'cuda-interop': cuda_interop.allowed() and (features['gl'] or features['vulkan'])}
if features['cuda-interop'] and features['gl']
sources += files('video/out/hwdec/hwdec_cuda_gl.c')
endif
if features['cuda-interop'] and features['vulkan']
sources += files('video/out/hwdec/hwdec_cuda_vk.c')
endif
vulkan_interop = get_option('vulkan-interop').require(
features['vulkan'] and vulkan.version().version_compare('>=1.3.238') and
libavutil.version().version_compare('>=58.11.100'),
error_message: 'Vulkan Interop requires vulkan headers >= 1.3.238, and libavutil >= 58.11.100',
)
features += {'vulkan-interop': vulkan_interop.allowed()}
if vulkan_interop.allowed()
sources += files('video/out/hwdec/hwdec_vulkan.c')
endif
d3d_hwaccel = get_option('d3d-hwaccel').require(
win32,
error_message: 'the os is not win32!',
)
features += {'d3d-hwaccel': d3d_hwaccel.allowed()}
if features['d3d-hwaccel']
sources += files('video/d3d.c',
'video/filter/vf_d3d11vpp.c')
endif
if features['d3d-hwaccel'] and egl_angle.allowed()
sources += files('video/out/opengl/hwdec_d3d11egl.c')
endif
if features['d3d-hwaccel'] and features['d3d11']
sources += files('video/out/d3d11/hwdec_d3d11va.c')
endif
d3d9_hwaccel = get_option('d3d9-hwaccel').require(
features['d3d-hwaccel'],
error_message: 'd3d-hwaccel was not found!',
)
features += {'d3d9-hwaccel': d3d9_hwaccel.allowed()}
if features['d3d9-hwaccel'] and features['egl-angle']
sources += files('video/out/opengl/hwdec_dxva2egl.c')
endif
if features['d3d9-hwaccel'] and features['d3d11']
sources += files('video/out/d3d11/hwdec_dxva2dxgi.c')
endif
gl_dxinterop_d3d9 = get_option('gl-dxinterop-d3d9').require(
features['gl-dxinterop'] and features['d3d9-hwaccel'],
error_message: 'gl-dxinterop and d3d9-hwaccel were not found!',
)
features += {'gl-dxinterop-d3d9': gl_dxinterop_d3d9.allowed()}
if features['gl-dxinterop-d3d9']
sources += files('video/out/opengl/hwdec_dxva2gldx.c')
endif
ios_gl = cc.has_header_symbol('OpenGLES/ES3/glext.h', 'GL_RGB32F', required: get_option('ios-gl'))
features += {'ios-gl': ios_gl}
if features['ios-gl']
sources += files('video/out/opengl/hwdec_ios.m')
endif
rpi_mmal_opt = get_option('rpi-mmal').require(
features['rpi'],
error_message: 'rpi was not found!',
)
rpi_mmal = dependency('/opt/vc/lib/pkgconfig/mmal.pc', 'mmal', required: rpi_mmal_opt)
features += {'rpi-mmal': rpi_mmal.found()}
if features['rpi-mmal']
dependencies += rpi_mmal
sources += files('video/out/opengl/hwdec_rpi.c',
'video/out/vo_rpi.c')
endif
libva = dependency('libva', version: '>= 1.1.0', required: get_option('vaapi'))
vaapi_drm = dependency('libva-drm', version: '>= 1.1.0',
required: get_option('vaapi-drm').require(libva.found() and features['drm']))
features += {'vaapi-drm': vaapi_drm.found()}
if features['vaapi-drm']
dependencies += vaapi_drm
endif
vaapi_wayland = dependency('libva-wayland', version: '>= 1.1.0',
required: get_option('vaapi-wayland').require(libva.found() and features['wayland']))
features += {'vaapi-wayland': vaapi_wayland.found()}
if features['vaapi-wayland']
dependencies += vaapi_wayland
endif
vaapi_x11 = dependency('libva-x11', version: '>= 1.1.0',
required: get_option('vaapi-x11').require(libva.found() and features['x11']))
features += {'vaapi-x11': vaapi_x11.found()}
if features['vaapi-x11']
dependencies += vaapi_x11
sources += files('video/out/vo_vaapi.c')
endif
vaapi = get_option('vaapi').require(libva.found() and (features['vaapi-drm'] or
features['vaapi-wayland'] or features['vaapi-x11']))
features += {'vaapi': vaapi.allowed()}
if features['vaapi']
dependencies += libva
sources += files('video/filter/vf_vavpp.c',
'video/vaapi.c',
'video/out/hwdec/hwdec_vaapi.c',
'video/out/hwdec/dmabuf_interop_pl.c')
endif
dmabuf_interop_gl = features['egl'] and features['drm']
features += {'dmabuf-interop-gl': dmabuf_interop_gl}
if features['dmabuf-interop-gl']
sources += files('video/out/hwdec/dmabuf_interop_gl.c')
endif
vdpau_opt = get_option('vdpau').require(
features['x11'],
error_message: 'x11 was not found!',
)
vdpau = dependency('vdpau', version: '>= 0.2', required: vdpau_opt)
features += {'vdpau': vdpau.found()}
if features['vdpau']
dependencies += vdpau
sources += files('video/filter/vf_vdpaupp.c',
'video/out/vo_vdpau.c',
'video/vdpau.c',
'video/vdpau_mixer.c')
endif
features += {'vdpau-gl-x11': vdpau.found() and gl_x11.allowed()}
if features['vdpau'] and features['vdpau-gl-x11']
sources += files('video/out/opengl/hwdec_vdpau.c')
endif
videotoolbox_gl = get_option('videotoolbox-gl').require(
features['gl-cocoa'] or features['ios-gl'],
error_message: 'gl-cocoa nor ios-gl could be found!',
)
features += {'videotoolbox-gl': videotoolbox_gl.allowed()}
if features['videotoolbox-gl']
sources += files('video/out/opengl/hwdec_osx.c')
endif
# macOS features
macos_sdk_version_py = ''
if darwin
macos_sdk_version_py = find_program(join_paths(source_root, 'TOOLS', 'macos-sdk-version.py'),
required: true)
endif
macos_sdk_path = ''
macos_sdk_version = '0.0'
if darwin and macos_sdk_version_py.found()
macos_sdk_info = run_command(macos_sdk_version_py, check: true).stdout().split(',')
macos_sdk_path = macos_sdk_info[0].strip()
macos_sdk_version = macos_sdk_info[1]
endif
if macos_sdk_path != ''
message('Detected macOS sdk path: ' + macos_sdk_path)
endif
if macos_sdk_version != '0.0'
message('Detected macOS SDK: ' + macos_sdk_version)
add_languages('objc')
objc_link_flags = ['-isysroot', macos_sdk_path, '-L/usr/lib', '-L/usr/local/lib']
add_project_link_arguments(objc_link_flags, language: ['c', 'objc'])
endif
xcrun = find_program('xcrun', required: get_option('swift-build').require(darwin))
swift_ver = '0.0'
if xcrun.found()
swift_prog = find_program(run_command(xcrun, '-find', 'swift', check: true).stdout().strip())
swift_ver_string = run_command(swift_prog, '-version', check: true).stdout()
verRe = '''
#!/usr/bin/env python3
import re
import sys
verRe = re.compile("(?i)version\s?([\d.]+)")
swift_ver = verRe.search(sys.argv[1]).group(1)
sys.stdout.write(swift_ver)
'''
swift_ver = run_command(python, '-c', verRe, swift_ver_string, check: true).stdout()
message('Detected Swift version: ' + swift_ver)
endif
macos_10_11_features = get_option('macos-10-11-features').require(
macos_sdk_version.version_compare('>=10.11'),
error_message: 'a suitable macos sdk version could not be found!',
)
macos_10_12_2_features = get_option('macos-10-12-2-features').require(
macos_sdk_version.version_compare('>=10.12.2'),
error_message: 'a suitable macos sdk version could not be found!',
)
macos_10_14_features = get_option('macos-10-14-features').require(
macos_sdk_version.version_compare('>=10.14'),
error_message: 'a suitable macos sdk version could not be found!',
)
swift = get_option('swift-build').require(
darwin and macos_sdk_version.version_compare('>=10.10') and swift_ver.version_compare('>=4.1'),
error_message: 'A suitable macos sdk version or swift version could not be found!',
)
features += {'swift': swift.allowed()}
swift_sources = []
if features['cocoa'] and features['swift']
swift_sources += files('osdep/macos/libmpv_helper.swift',
'osdep/macos/log_helper.swift',
'osdep/macos/mpv_helper.swift',
'osdep/macos/precise_timer.swift',
'osdep/macos/swift_compat.swift',
'osdep/macos/swift_extensions.swift',
'video/out/mac/common.swift',
'video/out/mac/title_bar.swift',
'video/out/mac/view.swift',
'video/out/mac/window.swift')
endif
macos_cocoa_cb = get_option('macos-cocoa-cb').require(
features['cocoa'] and features['swift'],
error_message: 'Either cocoa or swift could not be found!',
)
features += {'macos-cocoa-cb': macos_cocoa_cb.allowed()}
if features['macos-cocoa-cb']
swift_sources += files('video/out/cocoa_cb_common.swift',
'video/out/mac/gl_layer.swift')
endif
if features['cocoa'] and features['vulkan'] and features['swift']
swift_sources += files('video/out/mac_common.swift',
'video/out/mac/metal_layer.swift')
sources += files('video/out/vulkan/context_mac.m')
endif
macos_media_player = get_option('macos-media-player').require(
macos_10_12_2_features.allowed() and features['swift'],
error_message: 'Either the macos sdk version is not at least 10.12.2 or swift was not found!',
)
features += {'macos-media-player': macos_media_player.allowed()}
if features['macos-media-player']
swift_sources += files('osdep/macos/remote_command_center.swift')
endif
if features['swift'] and swift_sources.length() > 0
subdir('osdep')
endif
macos_touchbar = get_option('macos-touchbar').require(
features['cocoa'] and cc.has_header('AppKit/NSTouchBar.h'),
error_message: 'Either cocoa could not be found or AppKit/NSTouchBar.h could not be found!',
)
features += {'macos-touchbar': macos_touchbar.allowed()}
if features['macos-touchbar']
sources += files('osdep/macosx_touchbar.m')
endif
# manpages
manpage = 'DOCS/man/mpv.rst'
rst2man = find_program('rst2man', 'rst2man.py', required: get_option('manpage-build'))
features += {'manpage-build': rst2man.found()}
if features['manpage-build']
mandir = get_option('mandir')
custom_target('manpages',
input: manpage,
output: 'mpv.1',
command: [
docutils_wrapper, rst2man,
'--record-dependencies', '@DEPFILE@',
'--strip-elements-with-class=contents',
'@INPUT@', '@OUTPUT@'],
depfile: 'mpv.1.dep',
install: true,
install_dir: join_paths(mandir, 'man1')
)
endif
rst2html = find_program('rst2html', 'rst2html.py', required: get_option('html-build'))
features += {'html-build': rst2html.found()}
if features['html-build']
datadir = get_option('datadir')
custom_target('html-manpages',
input: manpage,
output: 'mpv.html',
command: [
docutils_wrapper, rst2html,
'--record-dependencies', '@DEPFILE@',
'@INPUT@', '@OUTPUT@'],
depfile: 'mpv.html.dep',
install: true,
install_dir: join_paths(datadir, 'doc', 'mpv')
)
endif
rst2pdf = find_program('rst2pdf', required: get_option('pdf-build'))
features += {'pdf-build': rst2pdf.found()}
if features['pdf-build']
dependency_file = rst2pdf.version().version_compare('>=0.100')
datadir = get_option('datadir')
custom_target('pdf-manpages',
input: manpage,
output: 'mpv.pdf',
command: [
docutils_wrapper, rst2pdf,
'-c', '-b', '1', '--repeat-table-rows',
dependency_file ? ['--record-dependencies', '@DEPFILE@'] : [],
'@INPUT@', '-o', '@OUTPUT@'],
depfile: 'mpv.pdf.dep',
install: true,
install_dir: join_paths(datadir, 'doc', 'mpv')
)
endif
if meson.version().version_compare('>= 1.1.0')
configuration = meson.build_options()
else
# Arbitrary hardcoded things to pass if the meson version is too
# old to have the build_options method.
configuration = 'meson configure build ' + '-Dprefix=' + get_option('prefix') + \
' -Dbuildtype=' + get_option('buildtype') + \
' -Doptimization=' + get_option('optimization')
endif
# Set config.h
conf_data = configuration_data()
conf_data.set_quoted('CONFIGURATION', configuration)
conf_data.set_quoted('DEFAULT_DVD_DEVICE', dvd_device)
conf_data.set_quoted('DEFAULT_CDROM_DEVICE', cd_device)
# Loop over all features in the build, create a define and add them to config.h
feature_keys = []
foreach feature, allowed: features
define = 'HAVE_@0@'.format(feature.underscorify().to_upper())
conf_data.set10(define, allowed)
# special handling for lua
if feature == 'lua' and allowed
feature_keys += lua_version
continue
endif
if allowed
feature_keys += feature
endif
endforeach
# Script to sort the feature_keys object.
feature_sort = '''
#!/usr/bin/env python3
import sys
features = " ".join(sorted(sys.argv[1:]))
sys.stdout.write(features)
'''
feature_str = run_command(python, '-c', feature_sort, feature_keys, check: true).stdout()
conf_data.set_quoted('FULLCONFIG', feature_str)
conf_data.set_quoted('MPV_CONFDIR', join_paths(get_option('prefix'), get_option('sysconfdir'), 'mpv'))
conf_data.set_quoted('PLATFORM', host_machine.system())
configure_file(output : 'config.h', configuration : conf_data)
message('List of enabled features: ' + feature_str)
# These are intentionally not added to conf_data.
features += {'cplayer': get_option('cplayer')}
features += {'libmpv-' + get_option('default_library'): get_option('libmpv')}
# build targets
if win32
windows = import('windows')
res_flags = ['--codepage=65001']
# Unintuitively, this compile operates out of the osdep subdirectory.
# Hence, these includes are needed.
res_includes = [source_root, build_root]
resources = ['etc/mpv-icon-8bit-16x16.png',
'etc/mpv-icon-8bit-32x32.png',
'etc/mpv-icon-8bit-64x64.png',
'etc/mpv-icon-8bit-128x128.png',
'etc/mpv-icon.ico',
'osdep/mpv.exe.manifest']
sources += windows.compile_resources('osdep/mpv.rc', args: res_flags, depend_files: resources,
depends: version_h, include_directories: res_includes)
endif
client_h_define = cc.get_define('MPV_CLIENT_API_VERSION', prefix: '#include "libmpv/client.h"',
include_directories: include_directories('.'))
major = client_h_define.split('|')[0].split('<<')[0].strip('() ')
minor = client_h_define.split('|')[1].strip('() ')
client_api_version = major + '.' + minor + '.0'
libmpv = library('mpv', sources, dependencies: dependencies, gnu_symbol_visibility: 'hidden',
link_args: cc.get_supported_link_arguments(['-Wl,-Bsymbolic']),
version: client_api_version, include_directories: includedir,
install: get_option('libmpv'), build_by_default: get_option('libmpv'))
if get_option('libmpv')
pkg = import('pkgconfig')
pkg.generate(libmpv, version: client_api_version,
description: 'mpv media player client library')
headers = ['libmpv/client.h', 'libmpv/render.h',
'libmpv/render_gl.h', 'libmpv/stream_cb.h']
install_headers(headers, subdir: 'mpv')
# Allow projects to build with libmpv by cloning into ./subprojects/mpv
libmpv_dep = declare_dependency(link_with: libmpv)
meson.override_dependency('mpv', libmpv_dep)
endif
if get_option('cplayer')
datadir = get_option('datadir')
confdir = get_option('sysconfdir')
conf_files = ['etc/mpv.conf', 'etc/input.conf',
'etc/mplayer-input.conf', 'etc/restore-old-bindings.conf']
install_data(conf_files, install_dir: join_paths(datadir, 'doc', 'mpv'))
bash_install_dir = join_paths(datadir, 'bash-completion', 'completions')
install_data('etc/mpv.bash-completion', install_dir: bash_install_dir, rename: 'mpv')
zsh_install_dir = join_paths(datadir, 'zsh', 'site-functions')
install_data('etc/_mpv.zsh', install_dir: zsh_install_dir, rename: '_mpv')
install_data('etc/mpv.desktop', install_dir: join_paths(datadir, 'applications'))
install_data('etc/mpv.metainfo.xml', install_dir: join_paths(datadir, 'metainfo'))
install_data('etc/encoding-profiles.conf', install_dir: join_paths(confdir, 'mpv'))
foreach size: ['16x16', '32x32', '64x64', '128x128']
icon_dir = join_paths(datadir, 'icons', 'hicolor', size, 'apps')
install_data('etc/mpv-icon-8bit-' + size + '.png', install_dir: icon_dir, rename: 'mpv.png')
endforeach
hicolor_dir = join_paths(datadir, 'icons', 'hicolor')
install_data('etc/mpv-gradient.svg', install_dir: join_paths(hicolor_dir, 'scalable', 'apps'),
rename: 'mpv.svg')
install_data('etc/mpv-symbolic.svg', install_dir: join_paths(hicolor_dir, 'symbolic', 'apps'))
mpv = executable('mpv', objects: libmpv.extract_all_objects(recursive: true), dependencies: dependencies,
win_subsystem: 'windows,6.0', include_directories: includedir, install: true)
endif
if get_option('tests')
subdir('test')
endif
summary({'d3d11': features['d3d11'],
'javascript': features['javascript'],
'libmpv': get_option('libmpv'),
'lua': features['lua'],
'opengl': features['gl'],
'vulkan': features['vulkan'],
'wayland': features['wayland'],
'x11': features['x11']},
bool_yn: true)