diff options
Diffstat (limited to 'third_party/dav1d/meson.build')
-rw-r--r-- | third_party/dav1d/meson.build | 491 |
1 files changed, 491 insertions, 0 deletions
diff --git a/third_party/dav1d/meson.build b/third_party/dav1d/meson.build new file mode 100644 index 0000000000..bab318857e --- /dev/null +++ b/third_party/dav1d/meson.build @@ -0,0 +1,491 @@ +# Copyright © 2018-2022, VideoLAN and dav1d authors +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +project('dav1d', ['c'], + version: '1.1.0', + default_options: ['c_std=c99', + 'warning_level=2', + 'buildtype=release', + 'b_ndebug=if-release'], + meson_version: '>= 0.49.0') + +dav1d_soname_version = '6.8.0' +dav1d_api_version_array = dav1d_soname_version.split('.') +dav1d_api_version_major = dav1d_api_version_array[0] +dav1d_api_version_minor = dav1d_api_version_array[1] +dav1d_api_version_revision = dav1d_api_version_array[2] + +dav1d_src_root = meson.current_source_dir() +cc = meson.get_compiler('c') + +# Configuratin data for config.h +cdata = configuration_data() + +# Configuration data for config.asm +cdata_asm = configuration_data() + +# Include directories +dav1d_inc_dirs = include_directories(['.', 'include/dav1d', 'include']) + + + +# +# Option handling +# + +# Bitdepth option +dav1d_bitdepths = get_option('bitdepths') +foreach bitdepth : ['8', '16'] + cdata.set10('CONFIG_@0@BPC'.format(bitdepth), dav1d_bitdepths.contains(bitdepth)) +endforeach + +# ASM option +is_asm_enabled = (get_option('enable_asm') == true and + (host_machine.cpu_family() == 'x86' or + (host_machine.cpu_family() == 'x86_64' and cc.get_define('__ILP32__').strip() == '') or + host_machine.cpu_family() == 'aarch64' or + host_machine.cpu_family().startswith('arm') or + host_machine.cpu() == 'ppc64le')) +cdata.set10('HAVE_ASM', is_asm_enabled) + +if is_asm_enabled and get_option('b_sanitize') == 'memory' + error('asm causes false positive with memory sanitizer. Use \'-Denable_asm=false\'.') +endif + +cdata.set10('TRIM_DSP_FUNCTIONS', get_option('trim_dsp') == 'true' or + (get_option('trim_dsp') == 'if-release' and get_option('buildtype') == 'release')) + +# Logging option +cdata.set10('CONFIG_LOG', get_option('logging')) + +# +# OS/Compiler checks and defines +# + +# Arguments in test_args will be used even on feature tests +test_args = [] + +optional_arguments = [] +optional_link_arguments = [] + +if host_machine.system() in ['linux', 'gnu', 'emscripten'] + test_args += '-D_GNU_SOURCE' + add_project_arguments('-D_GNU_SOURCE', language: 'c') +endif + +if host_machine.system() == 'windows' + cdata.set('_WIN32_WINNT', '0x0601') + cdata.set('UNICODE', 1) # Define to 1 for Unicode (Wide Chars) APIs + cdata.set('_UNICODE', 1) # Define to 1 for Unicode (Wide Chars) APIs + cdata.set('__USE_MINGW_ANSI_STDIO', 1) # Define to force use of MinGW printf + cdata.set('_CRT_DECLARE_NONSTDC_NAMES', 1) # Define to get off_t from sys/types.h on MSVC + if cc.has_function('fseeko', prefix : '#include <stdio.h>', args : test_args) + cdata.set('_FILE_OFFSET_BITS', 64) # Not set by default by Meson on Windows + else + cdata.set('fseeko', '_fseeki64') + cdata.set('ftello', '_ftelli64') + endif + + if host_machine.cpu_family() == 'x86_64' + if cc.get_argument_syntax() != 'msvc' + optional_link_arguments += '-Wl,--dynamicbase,--nxcompat,--tsaware,--high-entropy-va' + endif + elif host_machine.cpu_family() == 'x86' or host_machine.cpu_family() == 'arm' + if cc.get_argument_syntax() == 'msvc' + optional_link_arguments += '/largeaddressaware' + else + optional_link_arguments += '-Wl,--dynamicbase,--nxcompat,--tsaware,--large-address-aware' + endif + endif + + # On Windows, we use a compatibility layer to emulate pthread + thread_dependency = [] + thread_compat_dep = declare_dependency(sources : files('src/win32/thread.c')) + + rt_dependency = [] + + rc_version_array = meson.project_version().split('.') + winmod = import('windows') + rc_data = configuration_data() + rc_data.set('PROJECT_VERSION_MAJOR', rc_version_array[0]) + rc_data.set('PROJECT_VERSION_MINOR', rc_version_array[1]) + rc_data.set('PROJECT_VERSION_REVISION', rc_version_array[2]) + rc_data.set('API_VERSION_MAJOR', dav1d_api_version_major) + rc_data.set('API_VERSION_MINOR', dav1d_api_version_minor) + rc_data.set('API_VERSION_REVISION', dav1d_api_version_revision) + rc_data.set('COPYRIGHT_YEARS', '2018-2023') +else + thread_dependency = dependency('threads') + thread_compat_dep = [] + + rt_dependency = [] + if cc.has_function('clock_gettime', prefix : '#include <time.h>', args : test_args) + cdata.set('HAVE_CLOCK_GETTIME', 1) + elif host_machine.system() not in ['darwin', 'ios', 'tvos'] + rt_dependency = cc.find_library('rt', required: false) + if not cc.has_function('clock_gettime', prefix : '#include <time.h>', args : test_args, dependencies : rt_dependency) + error('clock_gettime not found') + endif + cdata.set('HAVE_CLOCK_GETTIME', 1) + endif +endif + +# check for fseeko on android. It is not always available if _FILE_OFFSET_BITS is defined to 64 +have_fseeko = true +if host_machine.system() == 'android' + if not cc.has_function('fseeko', prefix : '#include <stdio.h>', args : test_args) + if cc.has_function('fseeko', prefix : '#include <stdio.h>', args : test_args + ['-U_FILE_OFFSET_BITS']) + warning('Files larger than 2 gigabytes might not be supported in the dav1d CLI tool.') + add_project_arguments('-U_FILE_OFFSET_BITS', language: 'c') + elif get_option('enable_tools') + error('dav1d CLI tool needs fseeko()') + else + have_fseeko = false + endif + endif +endif + +libdl_dependency = [] +if host_machine.system() == 'linux' + libdl_dependency = cc.find_library('dl', required : false) + if cc.has_function('dlsym', prefix : '#include <dlfcn.h>', args : test_args, dependencies : libdl_dependency) + cdata.set('HAVE_DLSYM', 1) + endif +endif + +libm_dependency = cc.find_library('m', required: false) + + +# Header checks + +stdatomic_dependencies = [] +if not cc.check_header('stdatomic.h') + if cc.get_id() == 'msvc' + # we have a custom replacement for MSVC + stdatomic_dependencies += declare_dependency( + include_directories : include_directories('include/compat/msvc'), + ) + elif cc.compiles('''int main() { int v = 0; return __atomic_fetch_add(&v, 1, __ATOMIC_SEQ_CST); }''', + name : 'GCC-style atomics', args : test_args) + stdatomic_dependencies += declare_dependency( + include_directories : include_directories('include/compat/gcc'), + ) + else + error('Atomics not supported') + endif +endif + +if host_machine.cpu_family().startswith('wasm') + # enable atomics + bulk-memory features + stdatomic_dependencies += thread_dependency.partial_dependency(compile_args: true) +endif + +if cc.check_header('unistd.h') + cdata.set('HAVE_UNISTD_H', 1) +endif + +if cc.check_header('io.h') + cdata.set('HAVE_IO_H', 1) +endif + +if cc.check_header('pthread_np.h') + cdata.set('HAVE_PTHREAD_NP_H', 1) + test_args += '-DHAVE_PTHREAD_NP_H' +endif + + +# Function checks + +if not cc.has_function('getopt_long', prefix : '#include <getopt.h>', args : test_args) + getopt_dependency = declare_dependency( + sources: files('tools/compat/getopt.c'), + include_directories : include_directories('include/compat'), + ) +else + getopt_dependency = [] +endif + +if cc.has_function('_aligned_malloc', prefix : '#include <malloc.h>', args : test_args) + cdata.set('HAVE_ALIGNED_MALLOC', 1) +elif cc.has_function('posix_memalign', prefix : '#include <stdlib.h>', args : test_args) + cdata.set('HAVE_POSIX_MEMALIGN', 1) +elif cc.has_function('memalign', prefix : '#include <malloc.h>', args : test_args) + cdata.set('HAVE_MEMALIGN', 1) +endif + +if (host_machine.cpu_family() == 'aarch64' or + host_machine.cpu_family().startswith('arm') or + host_machine.cpu() == 'ppc64le') + if cc.has_function('getauxval', prefix : '#include <sys/auxv.h>', args : test_args) + cdata.set('HAVE_GETAUXVAL', 1) + endif + if cc.has_function('elf_aux_info', prefix : '#include <sys/auxv.h>', args : test_args) + cdata.set('HAVE_ELF_AUX_INFO', 1) + endif +endif + +pthread_np_prefix = ''' +#include <pthread.h> +#ifdef HAVE_PTHREAD_NP_H +#include <pthread_np.h> +#endif +''' +if cc.has_function('pthread_getaffinity_np', prefix : pthread_np_prefix, args : test_args, dependencies : thread_dependency) + cdata.set('HAVE_PTHREAD_GETAFFINITY_NP', 1) +endif +if cc.has_function('pthread_setaffinity_np', prefix : pthread_np_prefix, args : test_args, dependencies : thread_dependency) + cdata.set('HAVE_PTHREAD_SETAFFINITY_NP', 1) +endif + +if cc.compiles('int x = _Generic(0, default: 0);', name: '_Generic', args: test_args) + cdata.set('HAVE_C11_GENERIC', 1) +endif + +# Compiler flag tests + +if cc.has_argument('-fvisibility=hidden') + add_project_arguments('-fvisibility=hidden', language: 'c') +else + warning('Compiler does not support -fvisibility=hidden, all symbols will be public!') +endif + +# Compiler flags that should be set +# But when the compiler does not supports them +# it is not an error and silently tolerated +if cc.get_argument_syntax() != 'msvc' + optional_arguments += [ + '-Wundef', + '-Werror=vla', + '-Wno-maybe-uninitialized', + '-Wno-missing-field-initializers', + '-Wno-unused-parameter', + '-Wstrict-prototypes', + '-Werror=missing-prototypes', + '-Wshorten-64-to-32', + ] + if host_machine.cpu_family() == 'x86' + optional_arguments += [ + '-msse2', + '-mfpmath=sse', + ] + endif +else + optional_arguments += [ + '-wd4028', # parameter different from declaration + '-wd4090', # broken with arrays of pointers + '-wd4996' # use of POSIX functions + ] +endif + +if (get_option('buildtype') != 'debug' and get_option('buildtype') != 'plain') + optional_arguments += '-fomit-frame-pointer' + optional_arguments += '-ffast-math' +endif + +if (host_machine.system() in ['darwin', 'ios', 'tvos'] and cc.get_id() == 'clang' and + cc.version().startswith('11')) + # Workaround for Xcode 11 -fstack-check bug, see #301 + optional_arguments += '-fno-stack-check' +endif + +add_project_arguments(cc.get_supported_arguments(optional_arguments), language : 'c') +add_project_link_arguments(cc.get_supported_link_arguments(optional_link_arguments), language : 'c') + +# libFuzzer related things +fuzzing_engine = get_option('fuzzing_engine') +if fuzzing_engine == 'libfuzzer' + if not cc.has_argument('-fsanitize=fuzzer') + error('fuzzing_engine libfuzzer requires "-fsanitize=fuzzer"') + endif + fuzzer_args = ['-fsanitize=fuzzer-no-link', '-fsanitize=fuzzer'] + add_project_arguments(cc.first_supported_argument(fuzzer_args), language : 'c') +endif + +cdata.set10('ENDIANNESS_BIG', host_machine.endian() == 'big') + +if host_machine.cpu_family().startswith('x86') + if get_option('stack_alignment') > 0 + stack_alignment = get_option('stack_alignment') + elif host_machine.cpu_family() == 'x86_64' or host_machine.system() in ['linux', 'darwin', 'ios', 'tvos'] + stack_alignment = 16 + else + stack_alignment = 4 + endif + cdata_asm.set('STACK_ALIGNMENT', stack_alignment) +endif + +cdata.set10('ARCH_AARCH64', host_machine.cpu_family() == 'aarch64' or host_machine.cpu() == 'arm64') +cdata.set10('ARCH_ARM', host_machine.cpu_family().startswith('arm') and host_machine.cpu() != 'arm64') +if (is_asm_enabled and + (host_machine.cpu_family() == 'aarch64' or + host_machine.cpu_family().startswith('arm'))) + + as_func_code = '''__asm__ ( +".func meson_test" +".endfunc" +); +''' + have_as_func = cc.compiles(as_func_code) + cdata.set10('HAVE_AS_FUNC', have_as_func) + + # fedora package build infrastructure uses a gcc specs file to enable + # '-fPIE' by default. The chosen way only adds '-fPIE' to the C compiler + # with integrated preprocessor. It is not added to the standalone + # preprocessor or the preprocessing stage of '.S' files. So we have to + # compile code to check if we have to define PIC for the arm asm to + # avoid absolute relocations when building for example checkasm. + check_pic_code = ''' +#if defined(PIC) +#error "PIC already defined" +#elif !(defined(__PIC__) || defined(__pic__)) +#error "no pic" +#endif +''' + if cc.compiles(check_pic_code) + cdata.set('PIC', '3') + endif +endif + +cdata.set10('ARCH_X86', host_machine.cpu_family().startswith('x86')) +cdata.set10('ARCH_X86_64', host_machine.cpu_family() == 'x86_64') +cdata.set10('ARCH_X86_32', host_machine.cpu_family() == 'x86') + +if host_machine.cpu_family().startswith('x86') + cdata_asm.set('private_prefix', 'dav1d') + cdata_asm.set10('ARCH_X86_64', host_machine.cpu_family() == 'x86_64') + cdata_asm.set10('ARCH_X86_32', host_machine.cpu_family() == 'x86') + cdata_asm.set10('PIC', true) + + # Convert SSE asm into (128-bit) AVX when compiler flags are set to use AVX instructions + cdata_asm.set10('FORCE_VEX_ENCODING', cc.get_define('__AVX__').strip() != '') +endif + +cdata.set10('ARCH_PPC64LE', host_machine.cpu() == 'ppc64le') + +# meson's cc.symbols_have_underscore_prefix() is unfortunately unrelieably +# when additional flags like '-fprofile-instr-generate' are passed via CFLAGS +# see following meson issue https://github.com/mesonbuild/meson/issues/5482 +if (host_machine.system() in ['darwin', 'ios', 'tvos'] or + (host_machine.system() == 'windows' and host_machine.cpu_family() == 'x86')) + cdata.set10('PREFIX', true) + cdata_asm.set10('PREFIX', true) +endif + +# +# ASM specific stuff +# +if is_asm_enabled and host_machine.cpu_family().startswith('x86') + + # NASM compiler support + + nasm = find_program('nasm') + + # check NASM version + if nasm.found() + nasm_r = run_command(nasm, '-v', check: true) + + out = nasm_r.stdout().strip().split() + if out[1].to_lower() == 'version' + if out[2].version_compare('<2.14') + error('nasm 2.14 or later is required, found nasm @0@'.format(out[2])) + endif + else + error('unexpected nasm version string: @0@'.format(nasm_r.stdout())) + endif + endif + + # Generate config.asm + config_asm_target = configure_file(output: 'config.asm', output_format: 'nasm', configuration: cdata_asm) + + if host_machine.system() == 'windows' + nasm_format = 'win' + elif host_machine.system() in ['darwin', 'ios', 'tvos'] + nasm_format = 'macho' + else + nasm_format = 'elf' + endif + if host_machine.cpu_family() == 'x86_64' + nasm_format += '64' + else + nasm_format += '32' + endif + + nasm_gen = generator(nasm, + output: '@BASENAME@.obj', + depfile: '@BASENAME@.obj.ndep', + arguments: [ + '-f', nasm_format, + '-I', '@0@/src/'.format(dav1d_src_root), + '-I', '@0@/'.format(meson.current_build_dir()), + '-MQ', '@OUTPUT@', '-MF', '@DEPFILE@', + '@EXTRA_ARGS@', + '@INPUT@', + '-o', '@OUTPUT@' + ]) +endif + +use_gaspp = false +if (is_asm_enabled and + (host_machine.cpu_family() == 'aarch64' or + host_machine.cpu_family().startswith('arm')) and + cc.get_argument_syntax() == 'msvc' and + (cc.get_id() != 'clang-cl' or meson.version().version_compare('<0.58.0'))) + gaspp = find_program('gas-preprocessor.pl') + use_gaspp = true + gaspp_gen = generator(gaspp, + output: '@BASENAME@.obj', + arguments: [ + '-as-type', 'armasm', + '-arch', host_machine.cpu_family(), + '--', + host_machine.cpu_family() == 'aarch64' ? 'armasm64' : 'armasm', + '-nologo', + '-I@0@'.format(dav1d_src_root), + '-I@0@/'.format(meson.current_build_dir()), + '@INPUT@', + '-c', + '-o', '@OUTPUT@' + ]) +endif + +# Generate config.h +config_h_target = configure_file(output: 'config.h', configuration: cdata) + + + +# +# Include subdir meson.build files +# The order is important! + +subdir('include') + +subdir('doc') + +subdir('src') + +subdir('tools') + +subdir('examples') + +subdir('tests') |