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