no bug - Import translations from android-l10n r=release a=l10n CLOSED TREE
[gecko.git] / third_party / dav1d / meson.build
blob6e49852103f7d6ab5a907860cb376f1d177a83a4
1 # Copyright © 2018-2022, VideoLAN and dav1d authors
2 # All rights reserved.
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are met:
7 # 1. Redistributions of source code must retain the above copyright notice, this
8 #    list of conditions and the following disclaimer.
10 # 2. Redistributions in binary form must reproduce the above copyright notice,
11 #    this list of conditions and the following disclaimer in the documentation
12 #    and/or other materials provided with the distribution.
14 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 project('dav1d', ['c'],
26     version: '1.4.0',
27     default_options: ['c_std=c99',
28                       'warning_level=2',
29                       'buildtype=release',
30                       'b_ndebug=if-release'],
31     meson_version: '>= 0.49.0')
33 dav1d_soname_version       = '7.0.0'
34 dav1d_api_version_array    = dav1d_soname_version.split('.')
35 dav1d_api_version_major    = dav1d_api_version_array[0]
36 dav1d_api_version_minor    = dav1d_api_version_array[1]
37 dav1d_api_version_revision = dav1d_api_version_array[2]
39 dav1d_src_root = meson.current_source_dir()
40 cc = meson.get_compiler('c')
42 # Configuratin data for config.h
43 cdata = configuration_data()
45 # Configuration data for config.asm
46 cdata_asm = configuration_data()
48 # Include directories
49 dav1d_inc_dirs = include_directories(['.', 'include/dav1d', 'include'])
54 # Option handling
57 # Bitdepth option
58 dav1d_bitdepths = get_option('bitdepths')
59 foreach bitdepth : ['8', '16']
60     cdata.set10('CONFIG_@0@BPC'.format(bitdepth), dav1d_bitdepths.contains(bitdepth))
61 endforeach
63 # ASM option
64 is_asm_enabled = (get_option('enable_asm') == true and
65     (host_machine.cpu_family() == 'aarch64' or
66      host_machine.cpu_family().startswith('arm') or
67      host_machine.cpu() == 'ppc64le' or
68      host_machine.cpu_family().startswith('riscv') or
69      host_machine.cpu_family().startswith('loongarch') or
70      host_machine.cpu_family() == 'x86' or
71      (host_machine.cpu_family() == 'x86_64' and cc.get_define('__ILP32__').strip() == '')))
72 cdata.set10('HAVE_ASM', is_asm_enabled)
74 if is_asm_enabled and get_option('b_sanitize') == 'memory'
75     error('asm causes false positive with memory sanitizer. Use \'-Denable_asm=false\'.')
76 endif
78 cdata.set10('TRIM_DSP_FUNCTIONS', get_option('trim_dsp') == 'true' or
79     (get_option('trim_dsp') == 'if-release' and get_option('buildtype') == 'release'))
81 # Logging option
82 cdata.set10('CONFIG_LOG', get_option('logging'))
85 # OS/Compiler checks and defines
88 # Arguments in test_args will be used even on feature tests
89 test_args = []
91 optional_arguments = []
92 optional_link_arguments = []
94 if host_machine.system() in ['linux', 'gnu', 'emscripten']
95     test_args += '-D_GNU_SOURCE'
96     add_project_arguments('-D_GNU_SOURCE', language: 'c')
97 endif
99 if host_machine.system() == 'windows'
100     cdata.set('_WIN32_WINNT',           '0x0601')
101     cdata.set('UNICODE',                1) # Define to 1 for Unicode (Wide Chars) APIs
102     cdata.set('_UNICODE',               1) # Define to 1 for Unicode (Wide Chars) APIs
103     cdata.set('__USE_MINGW_ANSI_STDIO', 1) # Define to force use of MinGW printf
104     cdata.set('_CRT_DECLARE_NONSTDC_NAMES', 1) # Define to get off_t from sys/types.h on MSVC
105     if cc.has_function('fseeko', prefix : '#include <stdio.h>', args : test_args)
106         cdata.set('_FILE_OFFSET_BITS', 64) # Not set by default by Meson on Windows
107     else
108         cdata.set('fseeko', '_fseeki64')
109         cdata.set('ftello', '_ftelli64')
110     endif
112     if host_machine.cpu_family() == 'x86_64'
113         if cc.get_argument_syntax() != 'msvc'
114             optional_link_arguments += '-Wl,--dynamicbase,--nxcompat,--tsaware,--high-entropy-va'
115         endif
116     elif host_machine.cpu_family() == 'x86' or host_machine.cpu_family() == 'arm'
117         if cc.get_argument_syntax() == 'msvc'
118             optional_link_arguments += '/largeaddressaware'
119         else
120             optional_link_arguments += '-Wl,--dynamicbase,--nxcompat,--tsaware,--large-address-aware'
121         endif
122     endif
124     # On Windows, we use a compatibility layer to emulate pthread
125     thread_dependency = []
126     thread_compat_dep = declare_dependency(sources : files('src/win32/thread.c'))
128     rt_dependency = []
130     rc_version_array = meson.project_version().split('.')
131     winmod = import('windows')
132     rc_data = configuration_data()
133     rc_data.set('PROJECT_VERSION_MAJOR', rc_version_array[0])
134     rc_data.set('PROJECT_VERSION_MINOR', rc_version_array[1])
135     rc_data.set('PROJECT_VERSION_REVISION', rc_version_array[2])
136     rc_data.set('API_VERSION_MAJOR', dav1d_api_version_major)
137     rc_data.set('API_VERSION_MINOR', dav1d_api_version_minor)
138     rc_data.set('API_VERSION_REVISION', dav1d_api_version_revision)
139     rc_data.set('COPYRIGHT_YEARS', '2018-2024')
140 else
141     thread_dependency = dependency('threads')
142     thread_compat_dep = []
144     rt_dependency = []
145     if cc.has_function('clock_gettime', prefix : '#include <time.h>', args : test_args)
146         cdata.set('HAVE_CLOCK_GETTIME', 1)
147     elif host_machine.system() not in ['darwin', 'ios', 'tvos']
148         rt_dependency = cc.find_library('rt', required: false)
149         if not cc.has_function('clock_gettime', prefix : '#include <time.h>', args : test_args, dependencies : rt_dependency)
150             error('clock_gettime not found')
151         endif
152         cdata.set('HAVE_CLOCK_GETTIME', 1)
153     endif
155     if cc.has_function('posix_memalign', prefix : '#include <stdlib.h>', args : test_args)
156         cdata.set('HAVE_POSIX_MEMALIGN', 1)
157     endif
158 endif
160 # check for fseeko on android. It is not always available if _FILE_OFFSET_BITS is defined to 64
161 have_fseeko = true
162 if host_machine.system() == 'android'
163     if not cc.has_function('fseeko', prefix : '#include <stdio.h>', args : test_args)
164         if cc.has_function('fseeko', prefix : '#include <stdio.h>', args : test_args + ['-U_FILE_OFFSET_BITS'])
165             warning('Files larger than 2 gigabytes might not be supported in the dav1d CLI tool.')
166             add_project_arguments('-U_FILE_OFFSET_BITS', language: 'c')
167         elif get_option('enable_tools')
168             error('dav1d CLI tool needs fseeko()')
169         else
170             have_fseeko = false
171         endif
172     endif
173 endif
175 libdl_dependency = []
176 if host_machine.system() == 'linux'
177     libdl_dependency = cc.find_library('dl', required : false)
178     if cc.has_function('dlsym', prefix : '#include <dlfcn.h>', args : test_args, dependencies : libdl_dependency)
179         cdata.set('HAVE_DLSYM', 1)
180     endif
181 endif
183 libm_dependency = cc.find_library('m', required: false)
186 # Header checks
188 stdatomic_dependencies = []
189 if not cc.check_header('stdatomic.h')
190     if cc.get_id() == 'msvc'
191         # we have a custom replacement for MSVC
192         stdatomic_dependencies += declare_dependency(
193             include_directories : include_directories('include/compat/msvc'),
194         )
195     elif cc.compiles('''int main() { int v = 0; return __atomic_fetch_add(&v, 1, __ATOMIC_SEQ_CST); }''',
196                      name : 'GCC-style atomics', args : test_args)
197         stdatomic_dependencies += declare_dependency(
198             include_directories : include_directories('include/compat/gcc'),
199         )
200     else
201         error('Atomics not supported')
202     endif
203 endif
205 if host_machine.cpu_family().startswith('wasm')
206     # enable atomics + bulk-memory features
207     stdatomic_dependencies += thread_dependency.partial_dependency(compile_args: true)
208 endif
210 if cc.check_header('unistd.h')
211     cdata.set('HAVE_UNISTD_H', 1)
212 endif
214 if cc.check_header('io.h')
215     cdata.set('HAVE_IO_H', 1)
216 endif
218 if cc.check_header('pthread_np.h')
219     cdata.set('HAVE_PTHREAD_NP_H', 1)
220     test_args += '-DHAVE_PTHREAD_NP_H'
221 endif
224 # Function checks
226 if not cc.has_function('getopt_long', prefix : '#include <getopt.h>', args : test_args)
227     getopt_dependency = declare_dependency(
228         sources: files('tools/compat/getopt.c'),
229         include_directories : include_directories('include/compat'),
230     )
231 else
232     getopt_dependency = []
233 endif
235 if (host_machine.cpu_family() == 'aarch64' or
236     host_machine.cpu_family().startswith('arm') or
237     host_machine.cpu_family().startswith('loongarch') or
238     host_machine.cpu() == 'ppc64le' or
239     host_machine.cpu_family().startswith('riscv'))
240     if cc.has_function('getauxval', prefix : '#include <sys/auxv.h>', args : test_args)
241         cdata.set('HAVE_GETAUXVAL', 1)
242     endif
243     if cc.has_function('elf_aux_info', prefix : '#include <sys/auxv.h>', args : test_args)
244         cdata.set('HAVE_ELF_AUX_INFO', 1)
245     endif
246 endif
248 pthread_np_prefix = '''
249 #include <pthread.h>
250 #ifdef HAVE_PTHREAD_NP_H
251 #include <pthread_np.h>
252 #endif
254 if cc.has_function('pthread_getaffinity_np', prefix : pthread_np_prefix, args : test_args, dependencies : thread_dependency)
255     cdata.set('HAVE_PTHREAD_GETAFFINITY_NP', 1)
256 endif
257 if cc.has_function('pthread_setaffinity_np', prefix : pthread_np_prefix, args : test_args, dependencies : thread_dependency)
258     cdata.set('HAVE_PTHREAD_SETAFFINITY_NP', 1)
259 endif
261 if cc.compiles('int x = _Generic(0, default: 0);', name: '_Generic', args: test_args)
262     cdata.set('HAVE_C11_GENERIC', 1)
263 endif
265 # Compiler flag tests
267 if cc.has_argument('-fvisibility=hidden')
268     add_project_arguments('-fvisibility=hidden', language: 'c')
269 else
270     warning('Compiler does not support -fvisibility=hidden, all symbols will be public!')
271 endif
273 # Compiler flags that should be set
274 # But when the compiler does not supports them
275 # it is not an error and silently tolerated
276 if cc.get_argument_syntax() != 'msvc'
277     optional_arguments += [
278       '-Wundef',
279       '-Werror=vla',
280       '-Wno-maybe-uninitialized',
281       '-Wno-missing-field-initializers',
282       '-Wno-unused-parameter',
283       '-Wstrict-prototypes',
284       '-Werror=missing-prototypes',
285       '-Wshorten-64-to-32',
286     ]
287     if host_machine.cpu_family() == 'x86'
288         optional_arguments += [
289           '-msse2',
290           '-mfpmath=sse',
291         ]
292     endif
293 else
294     optional_arguments += [
295       '-wd4028', # parameter different from declaration
296       '-wd4090', # broken with arrays of pointers
297       '-wd4996'  # use of POSIX functions
298     ]
299 endif
301 if (get_option('buildtype') != 'debug' and get_option('buildtype') != 'plain')
302     optional_arguments += '-fomit-frame-pointer'
303     optional_arguments += '-ffast-math'
304 endif
306 if (host_machine.system() in ['darwin', 'ios', 'tvos'] and cc.get_id() == 'clang' and
307     cc.version().startswith('11'))
308     # Workaround for Xcode 11 -fstack-check bug, see #301
309     optional_arguments += '-fno-stack-check'
310 endif
312 add_project_arguments(cc.get_supported_arguments(optional_arguments), language : 'c')
313 add_project_link_arguments(cc.get_supported_link_arguments(optional_link_arguments), language : 'c')
315 # libFuzzer related things
316 fuzzing_engine = get_option('fuzzing_engine')
317 if fuzzing_engine == 'libfuzzer'
318     if not cc.has_argument('-fsanitize=fuzzer')
319         error('fuzzing_engine libfuzzer requires "-fsanitize=fuzzer"')
320     endif
321     fuzzer_args = ['-fsanitize=fuzzer-no-link', '-fsanitize=fuzzer']
322     add_project_arguments(cc.first_supported_argument(fuzzer_args), language : 'c')
323 endif
325 cdata.set10('ENDIANNESS_BIG', host_machine.endian() == 'big')
327 if host_machine.cpu_family().startswith('x86')
328     if get_option('stack_alignment') > 0
329         stack_alignment = get_option('stack_alignment')
330     elif host_machine.cpu_family() == 'x86_64' or host_machine.system() in ['linux', 'darwin', 'ios', 'tvos']
331         stack_alignment = 16
332     else
333         stack_alignment = 4
334     endif
335     cdata_asm.set('STACK_ALIGNMENT', stack_alignment)
336 endif
338 cdata.set10('ARCH_AARCH64', host_machine.cpu_family() == 'aarch64' or host_machine.cpu() == 'arm64')
339 cdata.set10('ARCH_ARM',     host_machine.cpu_family().startswith('arm') and host_machine.cpu() != 'arm64')
340 if (is_asm_enabled and
341     (host_machine.cpu_family() == 'aarch64' or
342      host_machine.cpu_family().startswith('arm')))
344    as_func_code = '''__asm__ (
345 ".func meson_test"
346 ".endfunc"
349     have_as_func = cc.compiles(as_func_code)
350     cdata.set10('HAVE_AS_FUNC', have_as_func)
352     # fedora package build infrastructure uses a gcc specs file to enable
353     # '-fPIE' by default. The chosen way only adds '-fPIE' to the C compiler
354     # with integrated preprocessor. It is not added to the standalone
355     # preprocessor or the preprocessing stage of '.S' files. So we have to
356     # compile code to check if we have to define PIC for the arm asm to
357     # avoid absolute relocations when building for example checkasm.
358     check_pic_code = '''
359 #if defined(PIC)
360 #error "PIC already defined"
361 #elif !(defined(__PIC__) || defined(__pic__))
362 #error "no pic"
363 #endif
365     if cc.compiles(check_pic_code)
366         cdata.set('PIC', '3')
367     endif
368 endif
370 cdata.set10('ARCH_X86', host_machine.cpu_family().startswith('x86'))
371 cdata.set10('ARCH_X86_64', host_machine.cpu_family() == 'x86_64')
372 cdata.set10('ARCH_X86_32', host_machine.cpu_family() == 'x86')
374 if host_machine.cpu_family().startswith('x86')
375     cdata_asm.set('private_prefix', 'dav1d')
376     cdata_asm.set10('ARCH_X86_64', host_machine.cpu_family() == 'x86_64')
377     cdata_asm.set10('ARCH_X86_32', host_machine.cpu_family() == 'x86')
378     cdata_asm.set10('PIC', true)
380     # Convert SSE asm into (128-bit) AVX when compiler flags are set to use AVX instructions
381     cdata_asm.set10('FORCE_VEX_ENCODING', cc.get_define('__AVX__').strip() != '')
382 endif
384 cdata.set10('ARCH_PPC64LE', host_machine.cpu() == 'ppc64le')
386 cdata.set10('ARCH_RISCV', host_machine.cpu_family().startswith('riscv'))
387 cdata.set10('ARCH_RV32', host_machine.cpu_family() == 'riscv32')
388 cdata.set10('ARCH_RV64', host_machine.cpu_family() == 'riscv64')
390 cdata.set10('ARCH_LOONGARCH', host_machine.cpu_family().startswith('loongarch'))
391 cdata.set10('ARCH_LOONGARCH32', host_machine.cpu_family() == 'loongarch32')
392 cdata.set10('ARCH_LOONGARCH64', host_machine.cpu_family() == 'loongarch64')
394 # meson's cc.symbols_have_underscore_prefix() is unfortunately unrelieably
395 # when additional flags like '-fprofile-instr-generate' are passed via CFLAGS
396 # see following meson issue https://github.com/mesonbuild/meson/issues/5482
397 if (host_machine.system() in ['darwin', 'ios', 'tvos'] or
398    (host_machine.system() == 'windows' and host_machine.cpu_family() == 'x86'))
399     cdata.set10('PREFIX', true)
400     cdata_asm.set10('PREFIX', true)
401 endif
404 # ASM specific stuff
406 if is_asm_enabled and host_machine.cpu_family().startswith('x86')
408     # NASM compiler support
410     nasm = find_program('nasm')
412     # check NASM version
413     if nasm.found()
414         nasm_r = run_command(nasm, '-v', check: true)
416         out = nasm_r.stdout().strip().split()
417         if out[1].to_lower() == 'version'
418             if out[2].version_compare('<2.14')
419                 error('nasm 2.14 or later is required, found nasm @0@'.format(out[2]))
420             endif
421         else
422             error('unexpected nasm version string: @0@'.format(nasm_r.stdout()))
423         endif
424     endif
426     # Generate config.asm
427     config_asm_target = configure_file(output: 'config.asm', output_format: 'nasm', configuration: cdata_asm)
429     if host_machine.system() == 'windows'
430         nasm_format = 'win'
431     elif host_machine.system() in ['darwin', 'ios', 'tvos']
432         nasm_format = 'macho'
433     else
434         nasm_format = 'elf'
435     endif
436     if host_machine.cpu_family() == 'x86_64'
437         nasm_format += '64'
438     else
439         nasm_format += '32'
440     endif
442     nasm_gen = generator(nasm,
443         output: '@BASENAME@.obj',
444         depfile: '@BASENAME@.obj.ndep',
445         arguments: [
446             '-f', nasm_format,
447             '-I', '@0@/src/'.format(dav1d_src_root),
448             '-I', '@0@/'.format(meson.current_build_dir()),
449             '-MQ', '@OUTPUT@', '-MF', '@DEPFILE@',
450             '@EXTRA_ARGS@',
451             '@INPUT@',
452             '-o', '@OUTPUT@'
453         ])
454 endif
456 use_gaspp = false
457 if (is_asm_enabled and
458     (host_machine.cpu_family() == 'aarch64' or
459      host_machine.cpu_family().startswith('arm')) and
460     cc.get_argument_syntax() == 'msvc' and
461     (cc.get_id() != 'clang-cl' or meson.version().version_compare('<0.58.0')))
462     gaspp = find_program('gas-preprocessor.pl')
463     use_gaspp = true
464     gaspp_gen = generator(gaspp,
465         output: '@BASENAME@.obj',
466         arguments: [
467             '-as-type', 'armasm',
468             '-arch', host_machine.cpu_family(),
469             '--',
470             host_machine.cpu_family() == 'aarch64' ? 'armasm64' : 'armasm',
471             '-nologo',
472             '-I@0@'.format(dav1d_src_root),
473             '-I@0@/'.format(meson.current_build_dir()),
474             '@INPUT@',
475             '-c',
476             '-o', '@OUTPUT@'
477         ])
478 endif
480 # Generate config.h
481 config_h_target = configure_file(output: 'config.h', configuration: cdata)
486 # Include subdir meson.build files
487 # The order is important!
489 subdir('include')
491 subdir('doc')
493 subdir('src')
495 subdir('tools')
497 subdir('examples')
499 subdir('tests')