#! /usr/bin/env python # encoding: utf-8 import os FRAGMENT_VLA='''int main (int argc, char **argv) { char a[argc]; a[sizeof( a ) - 1] = 0; int N; return a[0]; }''' FRAGMENT_ALLOCA_H='''#include int main (void) { int foo=10; int * array = alloca(foo); }''' FRAGMENT_STDLIB_H='''#include #include int main (void) { int foo=10; int * array = alloca(foo); }''' FRAGMENT_LRINT='''#include #include int main (int argc, char **argv) { return lrint%s((%s)atof(argv[1])); }''' # assuming MSVC always enables NEON FRAGMENT_NEON='''#if !defined __ARM_NEON__ && !defined _MSC_VER #error #endif''' def options(opt): pass def configure(conf): if not conf.path.find_dir('opus') or not conf.path.find_dir('opus/src'): conf.fatal('Can\'t find opus submodule. Run `git submodule update --init --recursive`.') return if conf.check_cc(fragment=FRAGMENT_LRINT % ('', 'double'), msg = 'Checking for C99 lrint', use = 'M', mandatory = False): conf.define('HAVE_LRINT', 1) if conf.check_cc(fragment=FRAGMENT_LRINT % ('f', 'float'), msg = 'Checking for C99 lrintf', use = 'M', mandatory = False): conf.define('HAVE_LRINTF', 1) # Check for C99 variable-size arrays, or alloca() as fallback if conf.check_cc(fragment=FRAGMENT_VLA, msg = 'Checking for C99 VLA support', mandatory = False): conf.define('VAR_ARRAYS', 1) elif conf.check_cc(fragment=FRAGMENT_ALLOCA_H, msg = 'Checking for alloca in alloca.h header', mandatory = False): conf.define('USE_ALLOCA', 1) conf.define('HAVE_ALLOCA_H', 1) elif conf.check_cc(fragment=FRAGMENT_STDLIB_H, msg = 'Checking for alloca.h in stdlib.h', mandatory = False): conf.define('USE_ALLOCA', 1) if conf.env.DEST_CPU in ['thumb', 'arm']: if conf.check(header_name='arm_neon.h', mandatory = False): if conf.check(fragment=FRAGMENT_NEON, msg = 'Checking if compiler enabled NEON', mandatory = False): conf.env.HAVE_NEON = True conf.define('OPUS_ARM_MAY_HAVE_NEON_INTR', 1) conf.define('OPUS_ARM_PRESUME_NEON', 1) elif conf.env.DEST_CPU.startswith('x86'): if conf.check(header_name='xmmintrin.h', mandatory = False): if conf.env.COMPILER_CC != 'msvc': conf.env.CFLAGS += ['-msse'] conf.define('OPUS_X86_MAY_HAVE_SSE', 1) if conf.env.DEST_SIZEOF_VOID_P > 4: conf.define('OPUS_X86_PRESUME_SSE', 1) if conf.check(header_name='emmintrin.h', mandatory = False): if conf.env.COMPILER_CC != 'msvc': conf.env.CFLAGS += ['-msse2'] conf.define('OPUS_X86_MAY_HAVE_SSE2', 1) if conf.env.DEST_SIZEOF_VOID_P > 4: conf.define('OPUS_X86_PRESUME_SSE2', 1) # on x86_64 we enable both SSE and SSE2, so RTCD can be disabled (it's actually doesn't even build with RTCD enabled) if conf.env.DEST_SIZEOF_VOID_P == 4: if conf.check(header_name='cpuid.h', mandatory=False): conf.define('CPU_INFO_BY_C', 1) else: conf.define('CPU_INFO_BY_ASM', 1) conf.define('OPUS_HAVE_RTCD', 1) # if conf.check(header_name='smmintrin.h', mandatory = False): # if conf.env.COMPILER_CC != 'msvc': # conf.env.CFLAGS += ['-msse4.1'] # conf.define('OPUS_X86_MAY_HAVE_SSE4_1', 1) # if conf.check(header_name='immintrin.h', mandatory = False): # if conf.env.COMPILER_CC != 'msvc': # conf.env.CFLAGS += ['-mavx'] # conf.define('OPUS_X86_MAY_HAVE_AVX', 1) # TODO: ARM/x86 intrinsics detection # TODO: maybe call autotools/cmake/meson instead? def build(bld): sources = bld.path.ant_glob([ 'opus/src/*.c', 'opus/celt/*.c', 'opus/silk/*.c', 'opus/silk/float/*.c' ], excl = [ 'opus/src/repacketizer_demo.c', 'opus/src/opus_demo.c', 'opus/src/opus_compare.c', 'opus/celt/opus_custom_demo.c' ]) includes = ['opus', 'opus/include/', 'opus/celt/', 'opus/silk/', 'opus/silk/float/'] if bld.env.DEST_CPU in ['thumb', 'arm']: if bld.env.HAVE_NEON: sources += bld.path.ant_glob(['opus/silk/arm/*.c', 'opus/celt/arm/*.c']) includes += ['opus/silk/arm', 'opus/celt/arm'] elif bld.env.DEST_CPU.startswith('x86'): sources += ['opus/silk/x86/x86_silk_map.c', 'opus/celt/x86/pitch_sse.c', 'opus/celt/x86/pitch_sse2.c', 'opus/celt/x86/vq_sse2.c', 'opus/celt/x86/x86_celt_map.c', 'opus/celt/x86/x86cpu.c'] includes += ['opus/silk/x86', 'opus/celt/x86'] defines = ['OPUS_BUILD', 'FLOAT_APPROX', 'PACKAGE_VERSION="1.4.0"', 'CUSTOM_MODES', 'ENABLE_HARDENING'] bld.stlib( source = sources, target = 'opus', features = 'c', includes = includes, defines = defines, export_includes = ['opus/include/'] )