xref: /aosp_15_r20/external/libopus/meson.build (revision a58d3d2adb790c104798cd88c8a3aff4fa8b82cc)
1*a58d3d2aSXin Liproject('opus', 'c',
2*a58d3d2aSXin Li  version: run_command('meson/get-version.py', '--package-version', check: true).stdout().strip(),
3*a58d3d2aSXin Li  meson_version: '>=0.54.0',
4*a58d3d2aSXin Li  default_options: ['warning_level=2',
5*a58d3d2aSXin Li                    'c_std=gnu99',
6*a58d3d2aSXin Li                    'buildtype=debugoptimized'])
7*a58d3d2aSXin Li
8*a58d3d2aSXin Lilibversion = run_command('meson/get-version.py', '--libtool-version', check: true).stdout().strip()
9*a58d3d2aSXin Limacosversion = run_command('meson/get-version.py', '--darwin-version', check: true).stdout().strip()
10*a58d3d2aSXin Li
11*a58d3d2aSXin Licc = meson.get_compiler('c')
12*a58d3d2aSXin Lihost_system = host_machine.system()
13*a58d3d2aSXin Lihost_cpu_family = host_machine.cpu_family()
14*a58d3d2aSXin Litop_srcdir = meson.current_source_dir()
15*a58d3d2aSXin Litop_builddir = meson.current_build_dir()
16*a58d3d2aSXin Li
17*a58d3d2aSXin Liopus_includes = include_directories('.', 'include', 'celt', 'silk', 'dnn')
18*a58d3d2aSXin Liopus_public_includes = include_directories('include')
19*a58d3d2aSXin Li
20*a58d3d2aSXin Liadd_project_arguments('-DOPUS_BUILD', language: 'c')
21*a58d3d2aSXin Liadd_project_arguments('-DHAVE_CONFIG_H', language: 'c')
22*a58d3d2aSXin Li
23*a58d3d2aSXin Liif host_system == 'windows'
24*a58d3d2aSXin Li  if cc.get_argument_syntax() == 'msvc'
25*a58d3d2aSXin Li    add_project_arguments('-D_CRT_SECURE_NO_WARNINGS', language: 'c')
26*a58d3d2aSXin Li  endif
27*a58d3d2aSXin Liendif
28*a58d3d2aSXin Li
29*a58d3d2aSXin Liif cc.get_argument_syntax() == 'gnu'
30*a58d3d2aSXin Li  add_project_arguments('-D_FORTIFY_SOURCE=2', language: 'c')
31*a58d3d2aSXin Liendif
32*a58d3d2aSXin Li
33*a58d3d2aSXin Li# Check for extra compiler args
34*a58d3d2aSXin Liadditional_c_args = []
35*a58d3d2aSXin Liif cc.get_argument_syntax() != 'msvc'
36*a58d3d2aSXin Li  additional_c_args += [
37*a58d3d2aSXin Li    '-fvisibility=hidden',
38*a58d3d2aSXin Li    '-Wcast-align',
39*a58d3d2aSXin Li    '-Wnested-externs',
40*a58d3d2aSXin Li    '-Wshadow',
41*a58d3d2aSXin Li    '-Wstrict-prototypes',
42*a58d3d2aSXin Li  ]
43*a58d3d2aSXin Li
44*a58d3d2aSXin Li  # On Windows, -fstack-protector-strong adds a libssp-0.dll dependency and
45*a58d3d2aSXin Li  # prevents static linking
46*a58d3d2aSXin Li  if host_system != 'windows'
47*a58d3d2aSXin Li    additional_c_args += ['-fstack-protector-strong']
48*a58d3d2aSXin Li  endif
49*a58d3d2aSXin Liendif
50*a58d3d2aSXin Li
51*a58d3d2aSXin Liforeach arg : additional_c_args
52*a58d3d2aSXin Li  if cc.has_argument(arg)
53*a58d3d2aSXin Li    add_project_arguments(arg, language: 'c')
54*a58d3d2aSXin Li  endif
55*a58d3d2aSXin Liendforeach
56*a58d3d2aSXin Li
57*a58d3d2aSXin Li# Windows MSVC warnings
58*a58d3d2aSXin Liif cc.get_id() == 'msvc'
59*a58d3d2aSXin Li  # Ignore several spurious warnings.
60*a58d3d2aSXin Li  # If a warning is completely useless and spammy, use '/wdXXXX' to suppress it
61*a58d3d2aSXin Li  # If a warning is harmless but hard to fix, use '/woXXXX' so it's shown once
62*a58d3d2aSXin Li  # NOTE: Only add warnings here if you are sure they're spurious
63*a58d3d2aSXin Li  add_project_arguments('/wd4035', '/wd4715', '/wd4116', '/wd4046', '/wd4068',
64*a58d3d2aSXin Li    '/wd4820', '/wd4244', '/wd4255', '/wd4668',
65*a58d3d2aSXin Li    language : 'c')
66*a58d3d2aSXin Liendif
67*a58d3d2aSXin Li
68*a58d3d2aSXin Liopus_version = meson.project_version()
69*a58d3d2aSXin Li
70*a58d3d2aSXin Liopus_conf = configuration_data()
71*a58d3d2aSXin Liopus_conf.set('PACKAGE_BUGREPORT', '"[email protected]"')
72*a58d3d2aSXin Liopus_conf.set('PACKAGE_NAME', '"opus"')
73*a58d3d2aSXin Liopus_conf.set('PACKAGE_STRING', '"opus @0@"'.format(opus_version))
74*a58d3d2aSXin Liopus_conf.set('PACKAGE_TARNAME', '"opus"')
75*a58d3d2aSXin Liopus_conf.set('PACKAGE_URL', '""')
76*a58d3d2aSXin Liopus_conf.set('PACKAGE_VERSION', '"@0@"'.format(opus_version))
77*a58d3d2aSXin Li
78*a58d3d2aSXin Li# FIXME: optional Ne10 dependency
79*a58d3d2aSXin Lihave_arm_ne10 = false
80*a58d3d2aSXin Li
81*a58d3d2aSXin Lilibm = cc.find_library('m', required : false)
82*a58d3d2aSXin Li
83*a58d3d2aSXin Liopus_conf.set('HAVE_LRINTF', cc.has_function('lrintf', prefix: '#include <math.h>', dependencies: libm))
84*a58d3d2aSXin Liopus_conf.set('HAVE_LRINT', cc.has_function('lrint', prefix: '#include <math.h>', dependencies: libm))
85*a58d3d2aSXin Liopus_conf.set('HAVE___MALLOC_HOOK', cc.has_function('__malloc_hook', prefix: '#include <malloc.h>'))
86*a58d3d2aSXin Liopus_conf.set('HAVE_STDINT_H', cc.check_header('stdint.h'))
87*a58d3d2aSXin Li
88*a58d3d2aSXin Li# Check for restrict keyword
89*a58d3d2aSXin Lirestrict_tmpl = '''
90*a58d3d2aSXin Litypedef int * int_ptr;
91*a58d3d2aSXin Liint foo (int_ptr @0@ ip, int * @0@ baz[]) {
92*a58d3d2aSXin Li  return ip[0];
93*a58d3d2aSXin Li}
94*a58d3d2aSXin Liint main (int argc, char ** argv) {
95*a58d3d2aSXin Li  int s[1];
96*a58d3d2aSXin Li  int * @0@ t = s;
97*a58d3d2aSXin Li  t[0] = 0;
98*a58d3d2aSXin Li  return foo(t, (void *)0);
99*a58d3d2aSXin Li}'''
100*a58d3d2aSXin Li# Define restrict to the equivalent of the C99 restrict keyword, or to
101*a58d3d2aSXin Li# nothing if this is not supported.  Do not define if restrict is
102*a58d3d2aSXin Li# supported directly.
103*a58d3d2aSXin Liif not cc.compiles(restrict_tmpl.format('restrict'), name : 'restrict keyword')
104*a58d3d2aSXin Li  if cc.compiles(restrict_tmpl.format('__restrict'), name : '__restrict')
105*a58d3d2aSXin Li    opus_conf.set('restrict', '__restrict')
106*a58d3d2aSXin Li  elif cc.compiles(restrict_tmpl.format('__restrict__'), name : '__restrict__')
107*a58d3d2aSXin Li    opus_conf.set('restrict', '__restrict')
108*a58d3d2aSXin Li  elif cc.compiles(restrict_tmpl.format('_Restrict'), name : '_Restrict')
109*a58d3d2aSXin Li    opus_conf.set('restrict', '_Restrict')
110*a58d3d2aSXin Li  else
111*a58d3d2aSXin Li    opus_conf.set('restrict', '/**/')
112*a58d3d2aSXin Li  endif
113*a58d3d2aSXin Liendif
114*a58d3d2aSXin Li
115*a58d3d2aSXin Li# Check for C99 variable-size arrays, or alloca() as fallback
116*a58d3d2aSXin Limsg_use_alloca = false
117*a58d3d2aSXin Liif cc.compiles('''static int x;
118*a58d3d2aSXin Li                  char some_func (void) {
119*a58d3d2aSXin Li                    char a[++x];
120*a58d3d2aSXin Li                    a[sizeof a - 1] = 0;
121*a58d3d2aSXin Li                    int N;
122*a58d3d2aSXin Li                    return a[0];
123*a58d3d2aSXin Li                  }''', name : 'C99 variable-size arrays')
124*a58d3d2aSXin Li  opus_conf.set('VAR_ARRAYS', 1)
125*a58d3d2aSXin Li  msg_use_alloca = 'NO (using C99 variable-size arrays instead)'
126*a58d3d2aSXin Lielif cc.compiles('''#include <alloca.h>
127*a58d3d2aSXin Li                    void some_func (void) {
128*a58d3d2aSXin Li                      int foo=10;
129*a58d3d2aSXin Li                      int * array = alloca(foo);
130*a58d3d2aSXin Li                    }''', name : 'alloca (alloca.h)')
131*a58d3d2aSXin Li  opus_conf.set('USE_ALLOCA', true)
132*a58d3d2aSXin Li  opus_conf.set('HAVE_ALLOCA_H', true)
133*a58d3d2aSXin Li  msg_use_alloca = true
134*a58d3d2aSXin Lielif cc.compiles('''#include <malloc.h>
135*a58d3d2aSXin Li                    #include <stdlib.h>
136*a58d3d2aSXin Li                    void some_func (void) {
137*a58d3d2aSXin Li                      int foo=10;
138*a58d3d2aSXin Li                      int * array = alloca(foo);
139*a58d3d2aSXin Li                    }''', name : 'alloca (std)')
140*a58d3d2aSXin Li  opus_conf.set('USE_ALLOCA', true)
141*a58d3d2aSXin Li  msg_use_alloca = true
142*a58d3d2aSXin Liendif
143*a58d3d2aSXin Li
144*a58d3d2aSXin Liopts = [
145*a58d3d2aSXin Li  [ 'fixed-point', 'FIXED_POINT' ],
146*a58d3d2aSXin Li  [ 'fixed-point-debug', 'FIXED_DEBUG' ],
147*a58d3d2aSXin Li  [ 'custom-modes', 'CUSTOM_MODES' ],
148*a58d3d2aSXin Li  [ 'float-approx', 'FLOAT_APPROX' ],
149*a58d3d2aSXin Li  [ 'enable-deep-plc', 'ENABLE_DEEP_PLC' ],
150*a58d3d2aSXin Li  [ 'enable-dred', 'ENABLE_DRED' ],
151*a58d3d2aSXin Li  [ 'enable-osce', 'ENABLE_OSCE' ],
152*a58d3d2aSXin Li  [ 'assertions', 'ENABLE_ASSERTIONS' ],
153*a58d3d2aSXin Li  [ 'hardening', 'ENABLE_HARDENING' ],
154*a58d3d2aSXin Li  [ 'fuzzing', 'FUZZING' ],
155*a58d3d2aSXin Li  [ 'check-asm', 'OPUS_CHECK_ASM' ],
156*a58d3d2aSXin Li]
157*a58d3d2aSXin Li
158*a58d3d2aSXin Liforeach opt : opts
159*a58d3d2aSXin Li  # we assume these are all boolean options
160*a58d3d2aSXin Li  opt_foo = get_option(opt[0])
161*a58d3d2aSXin Li  if opt_foo
162*a58d3d2aSXin Li    opus_conf.set(opt[1], 1)
163*a58d3d2aSXin Li  endif
164*a58d3d2aSXin Li  set_variable('opt_' + opt[0].underscorify(), opt_foo)
165*a58d3d2aSXin Liendforeach
166*a58d3d2aSXin Li
167*a58d3d2aSXin Liopt_asm = get_option('asm')
168*a58d3d2aSXin Liopt_rtcd = get_option('rtcd')
169*a58d3d2aSXin Liopt_intrinsics = get_option('intrinsics')
170*a58d3d2aSXin Liextra_programs = get_option('extra-programs')
171*a58d3d2aSXin Liopt_tests = get_option('tests')
172*a58d3d2aSXin Li
173*a58d3d2aSXin Lidisable_float_api = not get_option('float-api')
174*a58d3d2aSXin Liif disable_float_api
175*a58d3d2aSXin Li  opus_conf.set('DISABLE_FLOAT_API', 1)
176*a58d3d2aSXin Liendif
177*a58d3d2aSXin Li
178*a58d3d2aSXin Liif not get_option('enable-dnn-debug-float')
179*a58d3d2aSXin Li  opus_conf.set('DISABLE_DEBUG_FLOAT', 1)
180*a58d3d2aSXin Liendif
181*a58d3d2aSXin Li
182*a58d3d2aSXin Li# This is for the description in the pkg-config .pc file
183*a58d3d2aSXin Liif opt_fixed_point
184*a58d3d2aSXin Li  pc_build = 'fixed-point'
185*a58d3d2aSXin Lielse
186*a58d3d2aSXin Li  pc_build = 'floating-point'
187*a58d3d2aSXin Liendif
188*a58d3d2aSXin Liif opt_custom_modes
189*a58d3d2aSXin Li  pc_build = pc_build + ', custom modes'
190*a58d3d2aSXin Liendif
191*a58d3d2aSXin Li
192*a58d3d2aSXin Lirtcd_support = []
193*a58d3d2aSXin Li# With GCC, Clang, ICC, etc, we differentiate between 'may support this SIMD'
194*a58d3d2aSXin Li# and 'presume we have this SIMD' by checking whether the SIMD / intrinsics can
195*a58d3d2aSXin Li# be compiled by the compiler as-is (presume) or with SIMD cflags (may have).
196*a58d3d2aSXin Li# With MSVC, the compiler will always build SIMD/intrinsics targeting all
197*a58d3d2aSXin Li# specific instruction sets supported by that version of the compiler. No
198*a58d3d2aSXin Li# special arguments are ever needed. If runtime CPU detection is not disabled,
199*a58d3d2aSXin Li# we must always assume that we only 'may have' it.
200*a58d3d2aSXin Liopus_can_presume_simd = true
201*a58d3d2aSXin Liif cc.get_argument_syntax() == 'msvc'
202*a58d3d2aSXin Li  if opt_rtcd.disabled()
203*a58d3d2aSXin Li    warning('Building with an MSVC-like compiler and runtime CPU detection is disabled. Outputs may not run on all @0@ CPUs.'.format(host_cpu_family))
204*a58d3d2aSXin Li  else
205*a58d3d2aSXin Li    opus_can_presume_simd = false
206*a58d3d2aSXin Li  endif
207*a58d3d2aSXin Liendif
208*a58d3d2aSXin Li
209*a58d3d2aSXin Liopus_arm_external_asm = false
210*a58d3d2aSXin Li
211*a58d3d2aSXin Liasm_tmpl = '''
212*a58d3d2aSXin Liint main (int argc, char ** argv) {
213*a58d3d2aSXin Li  __asm__("@0@");
214*a58d3d2aSXin Li  return 0;
215*a58d3d2aSXin Li}'''
216*a58d3d2aSXin Li
217*a58d3d2aSXin Liasm_optimization = []
218*a58d3d2aSXin Liinline_optimization = []
219*a58d3d2aSXin Liif not opt_asm.disabled()
220*a58d3d2aSXin Li  # Currently we only have inline asm for fixed-point
221*a58d3d2aSXin Li  if host_cpu_family == 'arm' and opt_fixed_point
222*a58d3d2aSXin Li    opus_conf.set('OPUS_ARM_ASM', true)
223*a58d3d2aSXin Li
224*a58d3d2aSXin Li    # Check if compiler supports gcc-style inline assembly
225*a58d3d2aSXin Li    if cc.compiles('''#ifdef __GNUC_MINOR__
226*a58d3d2aSXin Li                      #if (__GNUC__ * 1000 + __GNUC_MINOR__) < 3004
227*a58d3d2aSXin Li                      #error GCC before 3.4 has critical bugs compiling inline assembly
228*a58d3d2aSXin Li                      #endif
229*a58d3d2aSXin Li                      #endif
230*a58d3d2aSXin Li                      __asm__ (""::)''',
231*a58d3d2aSXin Li                   name : 'compiler supports gcc-style inline assembly')
232*a58d3d2aSXin Li
233*a58d3d2aSXin Li      opus_conf.set('OPUS_ARM_INLINE_ASM', 1)
234*a58d3d2aSXin Li
235*a58d3d2aSXin Li      # AS_ASM_ARM_EDSP
236*a58d3d2aSXin Li      if cc.compiles(asm_tmpl.format('qadd r3,r3,r3'),
237*a58d3d2aSXin Li                     name : 'assembler supports EDSP instructions on ARM')
238*a58d3d2aSXin Li        opus_conf.set('OPUS_ARM_INLINE_EDSP', 1)
239*a58d3d2aSXin Li        inline_optimization += ['ESDP']
240*a58d3d2aSXin Li      endif
241*a58d3d2aSXin Li
242*a58d3d2aSXin Li      # AS_ASM_ARM_MEDIA
243*a58d3d2aSXin Li      if cc.compiles(asm_tmpl.format('shadd8 r3,r3,r3'),
244*a58d3d2aSXin Li                     name : 'assembler supports ARMv6 media instructions on ARM')
245*a58d3d2aSXin Li        opus_conf.set('OPUS_ARM_INLINE_MEDIA', 1)
246*a58d3d2aSXin Li        inline_optimization += ['Media']
247*a58d3d2aSXin Li      endif
248*a58d3d2aSXin Li
249*a58d3d2aSXin Li      # AS_ASM_ARM_NEON
250*a58d3d2aSXin Li      if cc.compiles(asm_tmpl.format('vorr d0,d0,d0'),
251*a58d3d2aSXin Li                     name : 'assembler supports NEON instructions on ARM')
252*a58d3d2aSXin Li        opus_conf.set('OPUS_ARM_INLINE_NEON', 1)
253*a58d3d2aSXin Li        inline_optimization += ['NEON']
254*a58d3d2aSXin Li      endif
255*a58d3d2aSXin Li    endif
256*a58d3d2aSXin Li
257*a58d3d2aSXin Li    # We need Perl to translate RVCT-syntax asm to gas syntax
258*a58d3d2aSXin Li    perl = find_program('perl', required: get_option('asm'))
259*a58d3d2aSXin Li    if perl.found()
260*a58d3d2aSXin Li      opus_arm_external_asm = true
261*a58d3d2aSXin Li      # opus_arm_presume_* mean we can and will use those instructions
262*a58d3d2aSXin Li      # directly without doing runtime CPU detection.
263*a58d3d2aSXin Li      # opus_arm_may_have_* mean we can emit those instructions, but we can
264*a58d3d2aSXin Li      # only use them after runtime detection.
265*a58d3d2aSXin Li      # The same rules apply for x86 assembly and intrinsics.
266*a58d3d2aSXin Li
267*a58d3d2aSXin Li      opus_arm_may_have_edsp = opus_conf.has('OPUS_ARM_INLINE_EDSP')
268*a58d3d2aSXin Li      opus_arm_presume_edsp = opus_arm_may_have_edsp and opus_can_presume_simd
269*a58d3d2aSXin Li
270*a58d3d2aSXin Li      opus_arm_may_have_media = opus_conf.has('OPUS_ARM_INLINE_MEDIA')
271*a58d3d2aSXin Li      opus_arm_presume_media = opus_arm_may_have_media and opus_can_presume_simd
272*a58d3d2aSXin Li
273*a58d3d2aSXin Li      opus_arm_may_have_neon = opus_conf.has('OPUS_ARM_INLINE_NEON')
274*a58d3d2aSXin Li      opus_arm_presume_neon = opus_arm_may_have_neon and opus_can_presume_simd
275*a58d3d2aSXin Li
276*a58d3d2aSXin Li      if not opt_rtcd.disabled()
277*a58d3d2aSXin Li        if not opus_arm_may_have_edsp
278*a58d3d2aSXin Li          message('Trying to force-enable armv5e EDSP instructions...')
279*a58d3d2aSXin Li          # AS_ASM_ARM_EDSP_FORCE
280*a58d3d2aSXin Li          opus_arm_may_have_edsp = cc.compiles(asm_tmpl.format('.arch armv5te\n.object_arch armv4t\nqadd r3,r3,r3'),
281*a58d3d2aSXin Li                                               name : 'Assembler supports EDSP instructions on ARM (forced)')
282*a58d3d2aSXin Li        endif
283*a58d3d2aSXin Li        if not opus_arm_may_have_media
284*a58d3d2aSXin Li          message('Trying to force-enable ARMv6 media instructions...')
285*a58d3d2aSXin Li          opus_arm_may_have_media = cc.compiles(asm_tmpl.format('.arch armv6\n.object_arch armv4t\nshadd8 r3,r3,r3'),
286*a58d3d2aSXin Li                                                name : 'Assembler supports ARMv6 media instructions on ARM (forced)')
287*a58d3d2aSXin Li        endif
288*a58d3d2aSXin Li        if not opus_arm_may_have_neon
289*a58d3d2aSXin Li          message('Trying to force-enable NEON instructions...')
290*a58d3d2aSXin Li          opus_arm_may_have_neon = cc.compiles(asm_tmpl.format('.arch armv7-a\n.fpu neon\n.object_arch armv4t\nvorr d0,d0,d0'),
291*a58d3d2aSXin Li                                               name : 'Assembler supports NEON instructions on ARM (forced)')
292*a58d3d2aSXin Li        endif
293*a58d3d2aSXin Li      endif
294*a58d3d2aSXin Li
295*a58d3d2aSXin Li      if opus_arm_may_have_edsp
296*a58d3d2aSXin Li        opus_conf.set('OPUS_ARM_MAY_HAVE_EDSP', 1)
297*a58d3d2aSXin Li        if opus_arm_presume_edsp
298*a58d3d2aSXin Li          opus_conf.set('OPUS_ARM_PRESUME_EDSP', 1)
299*a58d3d2aSXin Li          asm_optimization += ['EDSP']
300*a58d3d2aSXin Li        else
301*a58d3d2aSXin Li          rtcd_support += ['EDSP']
302*a58d3d2aSXin Li        endif
303*a58d3d2aSXin Li      endif
304*a58d3d2aSXin Li      if opus_arm_may_have_media
305*a58d3d2aSXin Li        opus_conf.set('OPUS_ARM_MAY_HAVE_MEDIA', 1)
306*a58d3d2aSXin Li        if opus_arm_presume_media
307*a58d3d2aSXin Li          opus_conf.set('OPUS_ARM_PRESUME_MEDIA', 1)
308*a58d3d2aSXin Li          asm_optimization += ['Media']
309*a58d3d2aSXin Li        else
310*a58d3d2aSXin Li          rtcd_support += ['Media']
311*a58d3d2aSXin Li        endif
312*a58d3d2aSXin Li      endif
313*a58d3d2aSXin Li      if opus_arm_may_have_neon
314*a58d3d2aSXin Li        opus_conf.set('OPUS_ARM_MAY_HAVE_NEON', 1)
315*a58d3d2aSXin Li        if opus_arm_presume_neon
316*a58d3d2aSXin Li          opus_conf.set('OPUS_ARM_PRESUME_NEON', 1)
317*a58d3d2aSXin Li          asm_optimization += ['NEON']
318*a58d3d2aSXin Li        else
319*a58d3d2aSXin Li          rtcd_support += ['NEON']
320*a58d3d2aSXin Li        endif
321*a58d3d2aSXin Li      endif
322*a58d3d2aSXin Li      if opus_arm_may_have_dotprod
323*a58d3d2aSXin Li        opus_conf.set('OPUS_ARM_MAY_HAVE_DOTPROD', 1)
324*a58d3d2aSXin Li        if opus_arm_presume_dotprod
325*a58d3d2aSXin Li          opus_conf.set('OPUS_ARM_PRESUME_DOTPROD', 1)
326*a58d3d2aSXin Li          asm_optimization += ['DOTPROD']
327*a58d3d2aSXin Li        else
328*a58d3d2aSXin Li          rtcd_support += ['DOTPROD']
329*a58d3d2aSXin Li        endif
330*a58d3d2aSXin Li      endif
331*a58d3d2aSXin Li
332*a58d3d2aSXin Li      if cc.get_define('__APPLE__') != ''
333*a58d3d2aSXin Li        arm2gnu_args = ['--apple']
334*a58d3d2aSXin Li      else
335*a58d3d2aSXin Li        arm2gnu_args = []
336*a58d3d2aSXin Li      endif
337*a58d3d2aSXin Li    endif # found perl
338*a58d3d2aSXin Li  else # arm + enable fixed point
339*a58d3d2aSXin Li    if opt_asm.enabled()
340*a58d3d2aSXin Li      error('asm option is enabled, but no assembly support for ' + host_cpu_family)
341*a58d3d2aSXin Li    endif
342*a58d3d2aSXin Li  endif
343*a58d3d2aSXin Liendif # enable asm
344*a58d3d2aSXin Li
345*a58d3d2aSXin Li# Check whether we require assembly and we support assembly on this arch,
346*a58d3d2aSXin Li# but none were detected. Can happen because of incorrect compiler flags, such
347*a58d3d2aSXin Li# as missing -mfloat-abi=softfp on ARM32 softfp architectures.
348*a58d3d2aSXin Liif opt_asm.enabled() and (asm_optimization.length() + inline_optimization.length()) == 0
349*a58d3d2aSXin Li  error('asm option was enabled, but no assembly support was detected')
350*a58d3d2aSXin Liendif
351*a58d3d2aSXin Li
352*a58d3d2aSXin Li# XXX: NEON has hardfp vs softfp compiler configuration issues
353*a58d3d2aSXin Li# When targeting ARM32 softfp, we sometimes need to explicitly pass
354*a58d3d2aSXin Li# -mfloat-abi=softfp to enable NEON. F.ex., on Android. It should
355*a58d3d2aSXin Li# be set in the cross file.
356*a58d3d2aSXin Liarm_neon_intr_link_args = ['-mfpu=neon']
357*a58d3d2aSXin Liarm_dotprod_intr_link_args = ['-march=armv8.2-a+dotprod']
358*a58d3d2aSXin Li
359*a58d3d2aSXin Lihave_sse = false
360*a58d3d2aSXin Lihave_sse2 = false
361*a58d3d2aSXin Lihave_sse4_1 = false
362*a58d3d2aSXin Lihave_avx2 = false
363*a58d3d2aSXin Lihave_neon_intr = false
364*a58d3d2aSXin Lihave_dotprod_intr = false
365*a58d3d2aSXin Li
366*a58d3d2aSXin Liintrinsics_support = []
367*a58d3d2aSXin Liif not opt_intrinsics.disabled()
368*a58d3d2aSXin Li  if host_cpu_family in ['arm', 'aarch64']
369*a58d3d2aSXin Li    # Check for ARMv7/AArch64 neon intrinsics
370*a58d3d2aSXin Li    intrin_check = '''
371*a58d3d2aSXin Li    #include <arm_neon.h>
372*a58d3d2aSXin Li      int main (void) {
373*a58d3d2aSXin Li        static float32x4_t A0, A1, SUMM;
374*a58d3d2aSXin Li        SUMM = vmlaq_f32(SUMM, A0, A1);
375*a58d3d2aSXin Li        return (int)vgetq_lane_f32(SUMM, 0);
376*a58d3d2aSXin Li      }'''
377*a58d3d2aSXin Li    intrin_name = 'ARMv7/AArch64 NEON'
378*a58d3d2aSXin Li    if cc.links(intrin_check,
379*a58d3d2aSXin Li                name: 'compiler supports @0@ intrinsics'.format(intrin_name))
380*a58d3d2aSXin Li      opus_arm_presume_neon_intr = opus_can_presume_simd
381*a58d3d2aSXin Li      opus_arm_may_have_neon_intr = true
382*a58d3d2aSXin Li    else
383*a58d3d2aSXin Li      opus_arm_presume_neon_intr = false
384*a58d3d2aSXin Li      if cc.links(intrin_check,
385*a58d3d2aSXin Li                  args: arm_neon_intr_link_args,
386*a58d3d2aSXin Li                  name: 'compiler supports @0@ intrinsics with @1@'.format(intrin_name, ' '.join(arm_neon_intr_link_args)))
387*a58d3d2aSXin Li        opus_arm_may_have_neon_intr = true
388*a58d3d2aSXin Li      else
389*a58d3d2aSXin Li        opus_arm_may_have_neon_intr = false
390*a58d3d2aSXin Li      endif
391*a58d3d2aSXin Li    endif
392*a58d3d2aSXin Li
393*a58d3d2aSXin Li    if opus_arm_may_have_neon_intr
394*a58d3d2aSXin Li      have_neon_intr = true
395*a58d3d2aSXin Li      intrinsics_support += [intrin_name]
396*a58d3d2aSXin Li      opus_conf.set('OPUS_ARM_MAY_HAVE_NEON_INTR', 1)
397*a58d3d2aSXin Li      if opus_arm_presume_neon_intr
398*a58d3d2aSXin Li        opus_conf.set('OPUS_ARM_PRESUME_NEON_INTR', 1)
399*a58d3d2aSXin Li      else
400*a58d3d2aSXin Li        rtcd_support += [intrin_name]
401*a58d3d2aSXin Li        opus_neon_intr_args = arm_neon_intr_link_args
402*a58d3d2aSXin Li      endif
403*a58d3d2aSXin Li    else
404*a58d3d2aSXin Li      message('Compiler does not support @0@ intrinsics'.format(intrin_name))
405*a58d3d2aSXin Li    endif
406*a58d3d2aSXin Li
407*a58d3d2aSXin Li    # Check for aarch64 neon intrinsics
408*a58d3d2aSXin Li    intrin_check = '''
409*a58d3d2aSXin Li    #include <arm_neon.h>
410*a58d3d2aSXin Li      int main (void) {
411*a58d3d2aSXin Li        static int32_t IN;
412*a58d3d2aSXin Li        static int16_t OUT;
413*a58d3d2aSXin Li        OUT = vqmovns_s32(IN);
414*a58d3d2aSXin Li      }'''
415*a58d3d2aSXin Li    intrin_name = 'AArch64 NEON'
416*a58d3d2aSXin Li    if cc.links(intrin_check,
417*a58d3d2aSXin Li                name: 'compiler supports @0@ intrinsics'.format(intrin_name))
418*a58d3d2aSXin Li      opus_arm_presume_aarch64_neon_intr = opus_can_presume_simd
419*a58d3d2aSXin Li      opus_arm_may_have_aarch64_neon_intr = true
420*a58d3d2aSXin Li    else
421*a58d3d2aSXin Li      opus_arm_presume_aarch64_neon_intr = false
422*a58d3d2aSXin Li      if cc.links(intrin_check,
423*a58d3d2aSXin Li                  args: arm_neon_intr_link_args,
424*a58d3d2aSXin Li                  name: 'compiler supports @0@ intrinsics with @1@'.format(intrin_name, ' '.join(arm_neon_intr_link_args)))
425*a58d3d2aSXin Li        opus_arm_may_have_aarch64_neon_intr = true
426*a58d3d2aSXin Li      else
427*a58d3d2aSXin Li        opus_arm_may_have_aarch64_neon_intr = false
428*a58d3d2aSXin Li      endif
429*a58d3d2aSXin Li    endif
430*a58d3d2aSXin Li
431*a58d3d2aSXin Li    if opus_arm_may_have_aarch64_neon_intr
432*a58d3d2aSXin Li      intrinsics_support += [intrin_name]
433*a58d3d2aSXin Li      opus_conf.set('OPUS_X86_MAY_HAVE_AARCH64_NEON_INTR', 1)
434*a58d3d2aSXin Li      if opus_arm_presume_aarch64_neon_intr
435*a58d3d2aSXin Li        opus_conf.set('OPUS_X86_PRESUME_AARCH64_NEON_INTR', 1)
436*a58d3d2aSXin Li      endif
437*a58d3d2aSXin Li    else
438*a58d3d2aSXin Li      message('Compiler does not support @0@ intrinsics'.format(intrin_name))
439*a58d3d2aSXin Li    endif
440*a58d3d2aSXin Li
441*a58d3d2aSXin Li    # Check for ARMv8.2 dotprod intrinsics
442*a58d3d2aSXin Li    intrin_check = '''
443*a58d3d2aSXin Li    #include <arm_neon.h>
444*a58d3d2aSXin Li      int main (void) {
445*a58d3d2aSXin Li        static int8x16_t a, b;
446*a58d3d2aSXin Li        static int32x4_t SUMM;
447*a58d3d2aSXin Li        SUMM = vdotq_s32(SUMM, a, b);
448*a58d3d2aSXin Li        return (int)vgetq_lane_s32(SUMM, 0);
449*a58d3d2aSXin Li      }'''
450*a58d3d2aSXin Li    intrin_name = 'AArch64 DOTPROD'
451*a58d3d2aSXin Li    if cc.links(intrin_check,
452*a58d3d2aSXin Li                name: 'compiler supports @0@ intrinsics'.format(intrin_name))
453*a58d3d2aSXin Li      opus_arm_presume_dotprod_intr = opus_can_presume_simd
454*a58d3d2aSXin Li      opus_arm_may_have_dotprod_intr = true
455*a58d3d2aSXin Li    else
456*a58d3d2aSXin Li      opus_arm_presume_dotprod_intr = false
457*a58d3d2aSXin Li      if cc.links(intrin_check,
458*a58d3d2aSXin Li                  args: arm_dotprod_intr_link_args,
459*a58d3d2aSXin Li                  name: 'compiler supports @0@ intrinsics with @1@'.format(intrin_name, ' '.join(arm_dotprod_intr_link_args)))
460*a58d3d2aSXin Li        opus_arm_may_have_dotprod_intr = true
461*a58d3d2aSXin Li      else
462*a58d3d2aSXin Li        opus_arm_may_have_dotprod_intr = false
463*a58d3d2aSXin Li      endif
464*a58d3d2aSXin Li    endif
465*a58d3d2aSXin Li
466*a58d3d2aSXin Li    if opus_arm_may_have_dotprod_intr
467*a58d3d2aSXin Li      have_dotprod_intr = true
468*a58d3d2aSXin Li      intrinsics_support += [intrin_name]
469*a58d3d2aSXin Li      opus_conf.set('OPUS_ARM_MAY_HAVE_DOTPROD', 1)
470*a58d3d2aSXin Li      if opus_arm_presume_dotprod_intr
471*a58d3d2aSXin Li        opus_conf.set('OPUS_ARM_PRESUME_DOTPROD', 1)
472*a58d3d2aSXin Li      else
473*a58d3d2aSXin Li        rtcd_support += [intrin_name]
474*a58d3d2aSXin Li        opus_dotprod_intr_args = arm_dotprod_intr_link_args
475*a58d3d2aSXin Li      endif
476*a58d3d2aSXin Li    else
477*a58d3d2aSXin Li      message('Compiler does not support @0@ intrinsics'.format(intrin_name))
478*a58d3d2aSXin Li    endif
479*a58d3d2aSXin Li
480*a58d3d2aSXin Li  elif host_cpu_family in ['x86', 'x86_64']
481*a58d3d2aSXin Li    # XXX: allow external override/specification of the flags
482*a58d3d2aSXin Li    x86_intrinsics = [
483*a58d3d2aSXin Li      [ 'SSE', 'xmmintrin.h', '__m128', '_mm_setzero_ps()', ['-msse'] ],
484*a58d3d2aSXin Li      [ 'SSE2', 'emmintrin.h', '__m128i', '_mm_setzero_si128()', ['-msse2'] ],
485*a58d3d2aSXin Li      [ 'SSE4.1', 'smmintrin.h', '__m128i', '_mm_setzero_si128(); mtest = _mm_cmpeq_epi64(mtest, mtest)', ['-msse4.1'] ],
486*a58d3d2aSXin Li      [ 'AVX2', 'immintrin.h', '__m256i', '_mm256_abs_epi32(_mm256_setzero_si256())', ['-mavx', '-mfma', '-mavx2'] ],
487*a58d3d2aSXin Li    ]
488*a58d3d2aSXin Li
489*a58d3d2aSXin Li    foreach intrin : x86_intrinsics
490*a58d3d2aSXin Li      intrin_check = '''#include <@0@>
491*a58d3d2aSXin Li                        int main (int argc, char ** argv) {
492*a58d3d2aSXin Li                          static @1@ mtest;
493*a58d3d2aSXin Li                          mtest = @2@;
494*a58d3d2aSXin Li                          return *((unsigned char *) &mtest) != 0;
495*a58d3d2aSXin Li                        }'''.format(intrin[1],intrin[2],intrin[3])
496*a58d3d2aSXin Li      intrin_name = intrin[0]
497*a58d3d2aSXin Li      # Intrinsics arguments are not available with MSVC-like compilers
498*a58d3d2aSXin Li      intrin_args = cc.get_argument_syntax() == 'msvc' ? [] : intrin[4]
499*a58d3d2aSXin Li      if cc.links(intrin_check, name : 'compiler supports @0@ intrinsics'.format(intrin_name))
500*a58d3d2aSXin Li        may_have_intrin = true
501*a58d3d2aSXin Li        presume_intrin = opus_can_presume_simd
502*a58d3d2aSXin Li      elif intrin_args.length() > 0
503*a58d3d2aSXin Li        presume_intrin = false
504*a58d3d2aSXin Li        if cc.links(intrin_check,
505*a58d3d2aSXin Li                    args : intrin_args,
506*a58d3d2aSXin Li                    name : 'compiler supports @0@ intrinsics with @1@'.format(intrin_name, ' '.join(intrin_args)))
507*a58d3d2aSXin Li          may_have_intrin = true
508*a58d3d2aSXin Li        else
509*a58d3d2aSXin Li          may_have_intrin = false
510*a58d3d2aSXin Li        endif
511*a58d3d2aSXin Li      endif
512*a58d3d2aSXin Li      if may_have_intrin
513*a58d3d2aSXin Li        intrinsics_support += [intrin_name]
514*a58d3d2aSXin Li        intrin_lower_name = intrin_name.to_lower().underscorify()
515*a58d3d2aSXin Li        set_variable('have_' + intrin_lower_name, true)
516*a58d3d2aSXin Li        opus_conf.set('OPUS_X86_MAY_HAVE_' + intrin_name.underscorify(), 1)
517*a58d3d2aSXin Li        if presume_intrin
518*a58d3d2aSXin Li          opus_conf.set('OPUS_X86_PRESUME_' + intrin_name.underscorify(), 1)
519*a58d3d2aSXin Li        else
520*a58d3d2aSXin Li          rtcd_support += [intrin_name]
521*a58d3d2aSXin Li          set_variable('opus_@0@_args'.format(intrin_lower_name), intrin_args)
522*a58d3d2aSXin Li        endif
523*a58d3d2aSXin Li      else
524*a58d3d2aSXin Li        message('Compiler does not support @0@ intrinsics'.format(intrin_name))
525*a58d3d2aSXin Li      endif
526*a58d3d2aSXin Li    endforeach
527*a58d3d2aSXin Li
528*a58d3d2aSXin Li    if not opt_rtcd.disabled()
529*a58d3d2aSXin Li      get_cpuid_by_asm = false
530*a58d3d2aSXin Li      cpuid_asm_code = '''
531*a58d3d2aSXin Li        #include <stdio.h>
532*a58d3d2aSXin Li        int main (int argc, char ** argv) {
533*a58d3d2aSXin Li                 unsigned int CPUInfo0;
534*a58d3d2aSXin Li                 unsigned int CPUInfo1;
535*a58d3d2aSXin Li                 unsigned int CPUInfo2;
536*a58d3d2aSXin Li                 unsigned int CPUInfo3;
537*a58d3d2aSXin Li                 unsigned int InfoType;
538*a58d3d2aSXin Li                #if defined(__i386__) && defined(__PIC__)
539*a58d3d2aSXin Li                 __asm__ __volatile__ (
540*a58d3d2aSXin Li                 "xchg %%ebx, %1\n"
541*a58d3d2aSXin Li                 "cpuid\n"
542*a58d3d2aSXin Li                 "xchg %%ebx, %1\n":
543*a58d3d2aSXin Li                 "=a" (CPUInfo0),
544*a58d3d2aSXin Li                 "=r" (CPUInfo1),
545*a58d3d2aSXin Li                 "=c" (CPUInfo2),
546*a58d3d2aSXin Li                 "=d" (CPUInfo3) :
547*a58d3d2aSXin Li                 "a" (InfoType), "c" (0)
548*a58d3d2aSXin Li                );
549*a58d3d2aSXin Li               #else
550*a58d3d2aSXin Li                 __asm__ __volatile__ (
551*a58d3d2aSXin Li                 "cpuid":
552*a58d3d2aSXin Li                 "=a" (CPUInfo0),
553*a58d3d2aSXin Li                 "=b" (CPUInfo1),
554*a58d3d2aSXin Li                 "=c" (CPUInfo2),
555*a58d3d2aSXin Li                 "=d" (CPUInfo3) :
556*a58d3d2aSXin Li                 "a" (InfoType), "c" (0)
557*a58d3d2aSXin Li                );
558*a58d3d2aSXin Li               #endif
559*a58d3d2aSXin Li          return 0;
560*a58d3d2aSXin Li        }'''
561*a58d3d2aSXin Li      cpuid_c_code = '''
562*a58d3d2aSXin Li        #include <cpuid.h>
563*a58d3d2aSXin Li        int main (int argc, char ** argv) {
564*a58d3d2aSXin Li          unsigned int CPUInfo0;
565*a58d3d2aSXin Li          unsigned int CPUInfo1;
566*a58d3d2aSXin Li          unsigned int CPUInfo2;
567*a58d3d2aSXin Li          unsigned int CPUInfo3;
568*a58d3d2aSXin Li          unsigned int InfoType;
569*a58d3d2aSXin Li          __get_cpuid(InfoType, &CPUInfo0, &CPUInfo1, &CPUInfo2, &CPUInfo3);
570*a58d3d2aSXin Li          return 0;
571*a58d3d2aSXin Li        }'''
572*a58d3d2aSXin Li      cpuid_msvc_code = '''
573*a58d3d2aSXin Li        #include <intrin.h>
574*a58d3d2aSXin Li        int main (void) {
575*a58d3d2aSXin Li          int CPUInfo, InfoType;
576*a58d3d2aSXin Li          __cpuid(&CPUInfo, InfoType);
577*a58d3d2aSXin Li        }'''
578*a58d3d2aSXin Li      if cc.links(cpuid_asm_code, name : 'Get X86 CPU info via inline assembly')
579*a58d3d2aSXin Li        opus_conf.set('CPU_INFO_BY_ASM', 1)
580*a58d3d2aSXin Li      elif cc.links(cpuid_c_code, name : 'Get X86 CPU info via C method')
581*a58d3d2aSXin Li        opus_conf.set('CPU_INFO_BY_C', 1)
582*a58d3d2aSXin Li      elif cc.get_define('_MSC_VER') != '' and cc.links(cpuid_msvc_code)
583*a58d3d2aSXin Li        message('Getting X86 CPU info via __cpuid')
584*a58d3d2aSXin Li      else
585*a58d3d2aSXin Li        if opt_intrinsics.enabled() and opt_rtcd.enabled()
586*a58d3d2aSXin Li          error('intrinsics and rtcd options are enabled, but no Get CPU Info method detected')
587*a58d3d2aSXin Li        endif
588*a58d3d2aSXin Li        warning('Get CPU Info method not detected, no rtcd for intrinsics')
589*a58d3d2aSXin Li      endif
590*a58d3d2aSXin Li    endif # opt_rtcd
591*a58d3d2aSXin Li  else
592*a58d3d2aSXin Li    if opt_intrinsics.enabled()
593*a58d3d2aSXin Li      error('intrinsics option enabled, but no intrinsics support for ' + host_cpu_family)
594*a58d3d2aSXin Li    endif
595*a58d3d2aSXin Li    warning('No intrinsics support for ' + host_cpu_family)
596*a58d3d2aSXin Li  endif
597*a58d3d2aSXin Liendif
598*a58d3d2aSXin Li
599*a58d3d2aSXin Li# Check whether we require intrinsics and we support intrinsics on this arch,
600*a58d3d2aSXin Li# but none were detected. Can happen because of incorrect compiler flags, such
601*a58d3d2aSXin Li# as missing -mfloat-abi=softfp on ARM32 softfp architectures.
602*a58d3d2aSXin Liif opt_intrinsics.enabled() and intrinsics_support.length() == 0
603*a58d3d2aSXin Li  error('intrinsics option was enabled, but none were detected')
604*a58d3d2aSXin Liendif
605*a58d3d2aSXin Li
606*a58d3d2aSXin Liif opt_rtcd.disabled()
607*a58d3d2aSXin Li  rtcd_support = 'disabled'
608*a58d3d2aSXin Lielse
609*a58d3d2aSXin Li  if rtcd_support.length() > 0
610*a58d3d2aSXin Li    opus_conf.set('OPUS_HAVE_RTCD', 1)
611*a58d3d2aSXin Li  else
612*a58d3d2aSXin Li    if intrinsics_support.length() == 0
613*a58d3d2aSXin Li      rtcd_support = 'none'
614*a58d3d2aSXin Li      if opt_rtcd.enabled()
615*a58d3d2aSXin Li        error('rtcd option is enabled, but no support for intrinsics or assembly is available')
616*a58d3d2aSXin Li      endif
617*a58d3d2aSXin Li    else
618*a58d3d2aSXin Li      rtcd_support = 'not needed'
619*a58d3d2aSXin Li    endif
620*a58d3d2aSXin Li  endif
621*a58d3d2aSXin Liendif
622*a58d3d2aSXin Li
623*a58d3d2aSXin Li# extract source file lists from .mk files
624*a58d3d2aSXin Limk_files = [
625*a58d3d2aSXin Li  'opus_headers.mk', 'opus_sources.mk',
626*a58d3d2aSXin Li  'silk_headers.mk', 'silk_sources.mk',
627*a58d3d2aSXin Li  'celt_sources.mk', 'celt_headers.mk',
628*a58d3d2aSXin Li  'lpcnet_headers.mk', 'lpcnet_sources.mk',
629*a58d3d2aSXin Li]
630*a58d3d2aSXin Lilines = run_command('meson/read-sources-list.py', mk_files, check: true).stdout().strip().split('\n')
631*a58d3d2aSXin Lisources = {}
632*a58d3d2aSXin Liforeach l : lines
633*a58d3d2aSXin Li  a = l.split(' = ')
634*a58d3d2aSXin Li  var_name = a[0]
635*a58d3d2aSXin Li  file_list = a[1].split()
636*a58d3d2aSXin Li  sources += {var_name: files(file_list)}
637*a58d3d2aSXin Liendforeach
638*a58d3d2aSXin Li
639*a58d3d2aSXin Lisubdir('include')
640*a58d3d2aSXin Lisubdir('celt')
641*a58d3d2aSXin Lisubdir('silk')
642*a58d3d2aSXin Lisubdir('dnn')
643*a58d3d2aSXin Lisubdir('src')
644*a58d3d2aSXin Li
645*a58d3d2aSXin Liconfigure_file(output: 'config.h', configuration: opus_conf)
646*a58d3d2aSXin Li
647*a58d3d2aSXin Liif not opt_tests.disabled()
648*a58d3d2aSXin Li  subdir('celt/tests')
649*a58d3d2aSXin Li  subdir('silk/tests')
650*a58d3d2aSXin Li  subdir('tests')
651*a58d3d2aSXin Liendif
652*a58d3d2aSXin Li
653*a58d3d2aSXin Li# pkg-config files (not using pkg module so we can use the existing .pc.in file)
654*a58d3d2aSXin Lipkgconf = configuration_data()
655*a58d3d2aSXin Li
656*a58d3d2aSXin Lipkgconf.set('prefix', join_paths(get_option('prefix')))
657*a58d3d2aSXin Lipkgconf.set('exec_prefix', '${prefix}')
658*a58d3d2aSXin Lipkgconf.set('libdir', '${prefix}/@0@'.format(get_option('libdir')))
659*a58d3d2aSXin Lipkgconf.set('includedir', '${prefix}/@0@'.format(get_option('includedir')))
660*a58d3d2aSXin Lipkgconf.set('VERSION', opus_version)
661*a58d3d2aSXin Lipkgconf.set('PC_BUILD', pc_build)
662*a58d3d2aSXin Lipkgconf.set('LIBM', libm.found() ? '-lm' : '')
663*a58d3d2aSXin Li
664*a58d3d2aSXin Lipkg_install_dir = '@0@/pkgconfig'.format(get_option('libdir'))
665*a58d3d2aSXin Li
666*a58d3d2aSXin Liconfigure_file(input : 'opus.pc.in',
667*a58d3d2aSXin Li  output : 'opus.pc',
668*a58d3d2aSXin Li  configuration : pkgconf,
669*a58d3d2aSXin Li  install_dir : pkg_install_dir)
670*a58d3d2aSXin Li
671*a58d3d2aSXin Li# The uninstalled one has hardcoded libtool + static lib stuff, skip it for now
672*a58d3d2aSXin Li#configure_file(input : 'opus-uninstalled.pc.in',
673*a58d3d2aSXin Li#  output : 'opus-uninstalled.pc',
674*a58d3d2aSXin Li#  configuration : pkgconf,
675*a58d3d2aSXin Li#  install : false)
676*a58d3d2aSXin Li
677*a58d3d2aSXin Lidoxygen = find_program('doxygen', required: get_option('docs'))
678*a58d3d2aSXin Liif doxygen.found()
679*a58d3d2aSXin Li  subdir('doc')
680*a58d3d2aSXin Liendif
681*a58d3d2aSXin Li
682*a58d3d2aSXin Lisummary(
683*a58d3d2aSXin Li  {
684*a58d3d2aSXin Li    'C99 var arrays': opus_conf.has('VAR_ARRAYS'),
685*a58d3d2aSXin Li    'C99 lrintf': opus_conf.has('HAVE_LRINTF'),
686*a58d3d2aSXin Li    'Use alloca': msg_use_alloca,
687*a58d3d2aSXin Li  },
688*a58d3d2aSXin Li  section: 'Compiler support',
689*a58d3d2aSXin Li  bool_yn: true,
690*a58d3d2aSXin Li  list_sep: ', ',
691*a58d3d2aSXin Li)
692*a58d3d2aSXin Li
693*a58d3d2aSXin Li# Parse optimization status
694*a58d3d2aSXin Liforeach status : [['inline_optimization', opt_asm],
695*a58d3d2aSXin Li                  ['asm_optimization', opt_asm],
696*a58d3d2aSXin Li                  ['intrinsics_support', opt_intrinsics]]
697*a58d3d2aSXin Li  res = status[0]
698*a58d3d2aSXin Li  opt = status[1]
699*a58d3d2aSXin Li  resval = get_variable(res)
700*a58d3d2aSXin Li  if opt.disabled()
701*a58d3d2aSXin Li    set_variable(res, 'disabled')
702*a58d3d2aSXin Li  elif resval.length() == 0
703*a58d3d2aSXin Li    if host_cpu_family not in ['arm', 'aarch64', 'x86', 'x86_64']
704*a58d3d2aSXin Li      set_variable(res, 'No optimizations for your platform, please send patches')
705*a58d3d2aSXin Li    else
706*a58d3d2aSXin Li      set_variable(res, 'none')
707*a58d3d2aSXin Li    endif
708*a58d3d2aSXin Li  endif
709*a58d3d2aSXin Liendforeach
710*a58d3d2aSXin Li
711*a58d3d2aSXin Lisummary(
712*a58d3d2aSXin Li  {
713*a58d3d2aSXin Li    'Floating point support': not opt_fixed_point,
714*a58d3d2aSXin Li    'Fast float approximations': opt_float_approx,
715*a58d3d2aSXin Li    'Fixed point debugging': opt_fixed_point_debug,
716*a58d3d2aSXin Li    'Inline assembly optimizations': inline_optimization,
717*a58d3d2aSXin Li    'External assembly optimizations': asm_optimization,
718*a58d3d2aSXin Li    'Intrinsics optimizations': intrinsics_support,
719*a58d3d2aSXin Li    'Run-time CPU detection': rtcd_support,
720*a58d3d2aSXin Li  },
721*a58d3d2aSXin Li  section: 'Optimizations',
722*a58d3d2aSXin Li  bool_yn: true,
723*a58d3d2aSXin Li  list_sep: ', ',
724*a58d3d2aSXin Li)
725*a58d3d2aSXin Lisummary(
726*a58d3d2aSXin Li  {
727*a58d3d2aSXin Li    'Custom modes': opt_custom_modes,
728*a58d3d2aSXin Li    'Assertions': opt_assertions,
729*a58d3d2aSXin Li    'Hardening': opt_hardening,
730*a58d3d2aSXin Li    'Fuzzing': opt_fuzzing,
731*a58d3d2aSXin Li    'Check ASM': opt_check_asm,
732*a58d3d2aSXin Li    'API documentation': doxygen.found(),
733*a58d3d2aSXin Li    'Extra programs': not extra_programs.disabled(),
734*a58d3d2aSXin Li    'Tests': not opt_tests.disabled(),
735*a58d3d2aSXin Li  },
736*a58d3d2aSXin Li  section: 'General configuration',
737*a58d3d2aSXin Li  bool_yn: true,
738*a58d3d2aSXin Li  list_sep: ', ',
739*a58d3d2aSXin Li)
740