mirror of
https://github.com/xiph/opus.git
synced 2025-05-15 07:58:29 +00:00
Add support for Meson build system
Tested on: - Linux/x86* with gcc - Android armv7 arm64 x86 x86_64 with clang - Windows x86 x86_64 with Visual Studio 2017 - Windows x86 x86_64 with MinGW - macOS x86_64 with clang - iOS arm64 x86_64 with clang Co-authored by: Nirbheek Chauhan <nirbheek@centricular.com> https://gitlab.xiph.org/xiph/opus/-/merge_requests/13
This commit is contained in:
parent
034c1b61a2
commit
c2b542b6c0
15 changed files with 1114 additions and 1 deletions
|
@ -19,7 +19,7 @@ autoconf:
|
|||
script:
|
||||
- ./autogen.sh
|
||||
- ./configure
|
||||
- make
|
||||
- make -j4
|
||||
- make distcheck
|
||||
cache:
|
||||
paths:
|
||||
|
@ -40,3 +40,21 @@ cmake:
|
|||
- cmake -S . -B build -G "Ninja" -DCMAKE_BUILD_TYPE=Release -DOPUS_BUILD_TESTING=ON -DOPUS_BUILD_PROGRAMS=ON
|
||||
- cmake --build build
|
||||
- cd build && ctest --output-on-failure
|
||||
|
||||
meson:
|
||||
stage: build
|
||||
before_script:
|
||||
- apt-get update &&
|
||||
apt-get install -y python3-pip ninja-build doxygen
|
||||
- export XDG_CACHE_HOME=$PWD/pip-cache
|
||||
- pip3 install --user meson
|
||||
script:
|
||||
- export PATH=$PATH:$HOME/.local/bin
|
||||
- mkdir builddir
|
||||
- meson setup --werror -Dtests=enabled -Ddocs=enabled -Dbuildtype=release builddir
|
||||
- meson compile -C builddir
|
||||
- meson test -C builddir
|
||||
#- meson dist --no-tests -C builddir
|
||||
cache:
|
||||
paths:
|
||||
- 'pip-cache/*'
|
||||
|
|
12
Makefile.am
12
Makefile.am
|
@ -224,6 +224,18 @@ EXTRA_DIST = opus.pc.in \
|
|||
cmake/OpusSources.cmake \
|
||||
cmake/config.h.cmake.in \
|
||||
cmake/vla.c \
|
||||
meson/get-version.py \
|
||||
meson/read-sources-list.py \
|
||||
meson.build \
|
||||
meson_options.txt \
|
||||
include/meson.build \
|
||||
celt/meson.build \
|
||||
celt/tests/meson.build \
|
||||
silk/meson.build \
|
||||
silk/tests/meson.build \
|
||||
src/meson.build \
|
||||
tests/meson.build \
|
||||
doc/meson.build \
|
||||
tests/run_vectors.sh \
|
||||
celt/arm/arm2gnu.pl \
|
||||
celt/arm/celt_pitch_xcorr_arm.s \
|
||||
|
|
63
celt/meson.build
Normal file
63
celt/meson.build
Normal file
|
@ -0,0 +1,63 @@
|
|||
celt_sources = sources['CELT_SOURCES']
|
||||
|
||||
celt_sse_sources = sources['CELT_SOURCES_SSE']
|
||||
|
||||
celt_sse2_sources = sources['CELT_SOURCES_SSE2']
|
||||
|
||||
celt_sse4_1_sources = sources['CELT_SOURCES_SSE4_1']
|
||||
|
||||
celt_neon_intr_sources = sources['CELT_SOURCES_ARM_NEON_INTR']
|
||||
|
||||
celt_static_libs = []
|
||||
|
||||
foreach intr_name : ['sse', 'sse2', 'sse4_1', 'neon_intr']
|
||||
have_intr = get_variable('have_' + intr_name)
|
||||
if not have_intr
|
||||
continue
|
||||
endif
|
||||
|
||||
intr_sources = get_variable('celt_@0@_sources'.format(intr_name))
|
||||
intr_args = get_variable('opus_@0@_args'.format(intr_name), [])
|
||||
celt_static_libs += static_library('celt_' + intr_name, intr_sources,
|
||||
c_args: intr_args,
|
||||
include_directories: opus_includes,
|
||||
install: false)
|
||||
endforeach
|
||||
|
||||
have_arm_intrinsics_or_asm = have_arm_ne10
|
||||
if (intrinsics_support.length() + asm_optimization.length() + inline_optimization.length()) > 0
|
||||
have_arm_intrinsics_or_asm = true
|
||||
endif
|
||||
|
||||
if host_cpu_family in ['arm', 'aarch64'] and have_arm_intrinsics_or_asm
|
||||
celt_sources += sources['CELT_SOURCES_ARM']
|
||||
if have_arm_ne10
|
||||
celt_sources += sources['CELT_SOURCES_ARM_NE10']
|
||||
endif
|
||||
if opus_arm_external_asm
|
||||
arm2gnu = [find_program('arm/arm2gnu.pl')] + arm2gnu_args
|
||||
celt_sources_arm_asm = configure_file(input: 'arm/celt_pitch_xcorr_arm.s',
|
||||
output: '@BASENAME@-gnu.S',
|
||||
command: arm2gnu + ['@INPUT@'],
|
||||
capture: true)
|
||||
celt_arm_armopts_s = configure_file(input: 'arm/armopts.s.in',
|
||||
output: 'arm/armopts.s',
|
||||
configuration: opus_conf)
|
||||
celt_static_libs += static_library('celt-armasm',
|
||||
celt_arm_armopts_s, celt_sources_arm_asm,
|
||||
install: false)
|
||||
endif
|
||||
endif
|
||||
|
||||
celt_c_args = []
|
||||
if host_system == 'windows'
|
||||
celt_c_args += ['-DDLL_EXPORT']
|
||||
endif
|
||||
|
||||
celt_lib = static_library('opus-celt',
|
||||
celt_sources,
|
||||
c_args: celt_c_args,
|
||||
include_directories: opus_includes,
|
||||
link_whole: celt_static_libs,
|
||||
dependencies: libm,
|
||||
install: false)
|
19
celt/tests/meson.build
Normal file
19
celt/tests/meson.build
Normal file
|
@ -0,0 +1,19 @@
|
|||
tests = [
|
||||
'test_unit_types',
|
||||
'test_unit_mathops',
|
||||
'test_unit_entropy',
|
||||
'test_unit_laplace',
|
||||
'test_unit_dft',
|
||||
'test_unit_mdct',
|
||||
'test_unit_rotation',
|
||||
'test_unit_cwrs32',
|
||||
]
|
||||
|
||||
foreach test_name : tests
|
||||
exe = executable(test_name, '@0@.c'.format(test_name),
|
||||
include_directories : opus_includes,
|
||||
link_with : [celt_lib, celt_static_libs],
|
||||
dependencies : libm,
|
||||
install : false)
|
||||
test(test_name, exe)
|
||||
endforeach
|
|
@ -335,3 +335,6 @@ PREDEFINED = OPUS_EXPORT= \
|
|||
# configure time.
|
||||
#
|
||||
HAVE_DOT = @HAVE_DOT@
|
||||
|
||||
# move docs to the correct place
|
||||
OUTPUT_DIRECTORY = @top_builddir@/doc
|
||||
|
|
36
doc/meson.build
Normal file
36
doc/meson.build
Normal file
|
@ -0,0 +1,36 @@
|
|||
top_srcdir = meson.source_root()
|
||||
top_builddir = meson.build_root()
|
||||
|
||||
have_dot = find_program('dot', required: false).found()
|
||||
|
||||
doxyfile_conf = configuration_data()
|
||||
doxyfile_conf.set('VERSION', opus_version)
|
||||
doxyfile_conf.set('HAVE_DOT', have_dot)
|
||||
doxyfile_conf.set('top_srcdir', top_srcdir)
|
||||
doxyfile_conf.set('top_builddir', top_builddir)
|
||||
|
||||
doxyfile = configure_file(input: 'Doxyfile.in',
|
||||
output: 'Doxyfile',
|
||||
configuration: doxyfile_conf,
|
||||
install: false)
|
||||
|
||||
docdir = join_paths(get_option('datadir'), get_option('docdir'))
|
||||
|
||||
doc_inputs = [
|
||||
'customdoxygen.css',
|
||||
'footer.html',
|
||||
'header.html',
|
||||
'opus_logo.svg',
|
||||
top_srcdir + '/include/opus.h',
|
||||
top_srcdir + '/include/opus_multistream.h',
|
||||
top_srcdir + '/include/opus_defines.h',
|
||||
top_srcdir + '/include/opus_types.h',
|
||||
top_srcdir + '/include/opus_custom.h',
|
||||
]
|
||||
|
||||
custom_target('doc',
|
||||
input: [ doxyfile ] + doc_inputs,
|
||||
output: [ 'html' ],
|
||||
command: [ doxygen, doxyfile ],
|
||||
install_dir: docdir,
|
||||
install: true)
|
13
include/meson.build
Normal file
13
include/meson.build
Normal file
|
@ -0,0 +1,13 @@
|
|||
opus_headers = [
|
||||
'opus.h',
|
||||
'opus_multistream.h',
|
||||
'opus_projection.h',
|
||||
'opus_types.h',
|
||||
'opus_defines.h',
|
||||
]
|
||||
|
||||
if opt_custom_modes
|
||||
opus_headers += ['opus_custom.h']
|
||||
endif
|
||||
|
||||
install_headers(opus_headers, subdir: 'opus')
|
673
meson.build
Normal file
673
meson.build
Normal file
|
@ -0,0 +1,673 @@
|
|||
project('opus', 'c',
|
||||
version: run_command('meson/get-version.py', '--package-version', check: true).stdout().strip(),
|
||||
meson_version: '>=0.54.0',
|
||||
default_options: ['warning_level=2',
|
||||
'c_std=gnu99',
|
||||
'buildtype=debugoptimized'])
|
||||
|
||||
libversion = run_command('meson/get-version.py', '--libtool-version', check: true).stdout().strip()
|
||||
macosversion = run_command('meson/get-version.py', '--darwin-version', check: true).stdout().strip()
|
||||
|
||||
cc = meson.get_compiler('c')
|
||||
host_system = host_machine.system()
|
||||
host_cpu_family = host_machine.cpu_family()
|
||||
|
||||
opus_includes = include_directories('.', 'include', 'celt', 'silk')
|
||||
opus_public_includes = include_directories('include')
|
||||
|
||||
add_project_arguments('-DOPUS_BUILD', language: 'c')
|
||||
add_project_arguments('-DHAVE_CONFIG_H', language: 'c')
|
||||
|
||||
if host_system == 'windows'
|
||||
if cc.get_argument_syntax() == 'msvc'
|
||||
add_project_arguments('-D_CRT_SECURE_NO_WARNINGS', language: 'c')
|
||||
endif
|
||||
endif
|
||||
|
||||
if cc.get_argument_syntax() == 'gnu'
|
||||
add_project_arguments('-D_FORTIFY_SOURCE=2', language: 'c')
|
||||
endif
|
||||
|
||||
# Check for extra compiler args
|
||||
additional_c_args = []
|
||||
if cc.get_argument_syntax() != 'msvc'
|
||||
additional_c_args += [
|
||||
'-fvisibility=hidden',
|
||||
'-Wcast-align',
|
||||
'-Wnested-externs',
|
||||
'-Wshadow',
|
||||
'-Wstrict-prototypes',
|
||||
]
|
||||
|
||||
# On Windows, -fstack-protector-strong adds a libssp-0.dll dependency and
|
||||
# prevents static linking
|
||||
if host_system != 'windows'
|
||||
additional_c_args += ['-fstack-protector-strong']
|
||||
endif
|
||||
endif
|
||||
|
||||
foreach arg : additional_c_args
|
||||
if cc.has_argument(arg)
|
||||
add_project_arguments(arg, language: 'c')
|
||||
endif
|
||||
endforeach
|
||||
|
||||
# Windows MSVC warnings
|
||||
if cc.get_id() == 'msvc'
|
||||
# Ignore several spurious warnings.
|
||||
# If a warning is completely useless and spammy, use '/wdXXXX' to suppress it
|
||||
# If a warning is harmless but hard to fix, use '/woXXXX' so it's shown once
|
||||
# NOTE: Only add warnings here if you are sure they're spurious
|
||||
add_project_arguments('/wd4035', '/wd4715', '/wd4116', '/wd4046', '/wd4068',
|
||||
'/wd4820', '/wd4244', '/wd4255', '/wd4668',
|
||||
language : 'c')
|
||||
endif
|
||||
|
||||
opus_version = meson.project_version()
|
||||
|
||||
opus_conf = configuration_data()
|
||||
opus_conf.set('PACKAGE_BUGREPORT', '"opus@xiph.org"')
|
||||
opus_conf.set('PACKAGE_NAME', '"opus"')
|
||||
opus_conf.set('PACKAGE_STRING', '"opus @0@"'.format(opus_version))
|
||||
opus_conf.set('PACKAGE_TARNAME', '"opus"')
|
||||
opus_conf.set('PACKAGE_URL', '""')
|
||||
opus_conf.set('PACKAGE_VERSION', '"@0@"'.format(opus_version))
|
||||
|
||||
# FIXME: optional Ne10 dependency
|
||||
have_arm_ne10 = false
|
||||
|
||||
libm = cc.find_library('m', required : false)
|
||||
|
||||
opus_conf.set('HAVE_LRINTF', cc.has_function('lrintf', prefix: '#include <math.h>', dependencies: libm))
|
||||
opus_conf.set('HAVE_LRINT', cc.has_function('lrint', prefix: '#include <math.h>', dependencies: libm))
|
||||
opus_conf.set('HAVE___MALLOC_HOOK', cc.has_function('__malloc_hook', prefix: '#include <malloc.h>'))
|
||||
opus_conf.set('HAVE_STDINT_H', cc.check_header('stdint.h'))
|
||||
|
||||
# Check for restrict keyword
|
||||
restrict_tmpl = '''
|
||||
typedef int * int_ptr;
|
||||
int foo (int_ptr @0@ ip, int * @0@ baz[]) {
|
||||
return ip[0];
|
||||
}
|
||||
int main (int argc, char ** argv) {
|
||||
int s[1];
|
||||
int * @0@ t = s;
|
||||
t[0] = 0;
|
||||
return foo(t, (void *)0);
|
||||
}'''
|
||||
# Define restrict to the equivalent of the C99 restrict keyword, or to
|
||||
# nothing if this is not supported. Do not define if restrict is
|
||||
# supported directly.
|
||||
if not cc.compiles(restrict_tmpl.format('restrict'), name : 'restrict keyword')
|
||||
if cc.compiles(restrict_tmpl.format('__restrict'), name : '__restrict')
|
||||
opus_conf.set('restrict', '__restrict')
|
||||
elif cc.compiles(restrict_tmpl.format('__restrict__'), name : '__restrict__')
|
||||
opus_conf.set('restrict', '__restrict')
|
||||
elif cc.compiles(restrict_tmpl.format('_Restrict'), name : '_Restrict')
|
||||
opus_conf.set('restrict', '_Restrict')
|
||||
else
|
||||
opus_conf.set('restrict', '/**/')
|
||||
endif
|
||||
endif
|
||||
|
||||
# Check for C99 variable-size arrays, or alloca() as fallback
|
||||
msg_use_alloca = false
|
||||
if cc.compiles('''static int x;
|
||||
char some_func (void) {
|
||||
char a[++x];
|
||||
a[sizeof a - 1] = 0;
|
||||
int N;
|
||||
return a[0];
|
||||
}''', name : 'C99 variable-size arrays')
|
||||
opus_conf.set('VAR_ARRAYS', 1)
|
||||
msg_use_alloca = 'NO (using C99 variable-size arrays instead)'
|
||||
elif cc.compiles('''#include <alloca.h>
|
||||
void some_func (void) {
|
||||
int foo=10;
|
||||
int * array = alloca(foo);
|
||||
}''', name : 'alloca (alloca.h)')
|
||||
opus_conf.set('USE_ALLOCA', true)
|
||||
opus_conf.set('HAVE_ALLOCA_H', true)
|
||||
msg_use_alloca = true
|
||||
elif cc.compiles('''#include <malloc.h>
|
||||
#include <stdlib.h>
|
||||
void some_func (void) {
|
||||
int foo=10;
|
||||
int * array = alloca(foo);
|
||||
}''', name : 'alloca (std)')
|
||||
opus_conf.set('USE_ALLOCA', true)
|
||||
msg_use_alloca = true
|
||||
endif
|
||||
|
||||
opts = [
|
||||
[ 'fixed-point', 'FIXED_POINT' ],
|
||||
[ 'fixed-point-debug', 'FIXED_DEBUG' ],
|
||||
[ 'custom-modes', 'CUSTOM_MODES' ],
|
||||
[ 'float-approx', 'FLOAT_APPROX' ],
|
||||
[ 'assertions', 'ENABLE_ASSERTIONS' ],
|
||||
[ 'hardening', 'ENABLE_HARDENING' ],
|
||||
[ 'fuzzing', 'FUZZING' ],
|
||||
[ 'check-asm', 'OPUS_CHECK_ASM' ],
|
||||
]
|
||||
|
||||
foreach opt : opts
|
||||
# we assume these are all boolean options
|
||||
opt_foo = get_option(opt[0])
|
||||
if opt_foo
|
||||
opus_conf.set(opt[1], 1)
|
||||
endif
|
||||
set_variable('opt_' + opt[0].underscorify(), opt_foo)
|
||||
endforeach
|
||||
|
||||
opt_asm = get_option('asm')
|
||||
opt_rtcd = get_option('rtcd')
|
||||
opt_intrinsics = get_option('intrinsics')
|
||||
extra_programs = get_option('extra-programs')
|
||||
opt_tests = get_option('tests')
|
||||
|
||||
disable_float_api = not get_option('float-api')
|
||||
if disable_float_api
|
||||
opus_conf.set('DISABLE_FLOAT_API', 1)
|
||||
endif
|
||||
|
||||
# This is for the description in the pkg-config .pc file
|
||||
if opt_fixed_point
|
||||
pc_build = 'fixed-point'
|
||||
else
|
||||
pc_build = 'floating-point'
|
||||
endif
|
||||
if opt_custom_modes
|
||||
pc_build = pc_build + ', custom modes'
|
||||
endif
|
||||
|
||||
rtcd_support = []
|
||||
# With GCC, Clang, ICC, etc, we differentiate between 'may support this SIMD'
|
||||
# and 'presume we have this SIMD' by checking whether the SIMD / intrinsics can
|
||||
# be compiled by the compiler as-is (presume) or with SIMD cflags (may have).
|
||||
# With MSVC, the compiler will always build SIMD/intrinsics targeting all
|
||||
# specific instruction sets supported by that version of the compiler. No
|
||||
# special arguments are ever needed. If runtime CPU detection is not disabled,
|
||||
# we must always assume that we only 'may have' it.
|
||||
opus_can_presume_simd = true
|
||||
if cc.get_argument_syntax() == 'msvc'
|
||||
if opt_rtcd.disabled()
|
||||
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))
|
||||
else
|
||||
opus_can_presume_simd = false
|
||||
endif
|
||||
endif
|
||||
|
||||
opus_arm_external_asm = false
|
||||
|
||||
asm_tmpl = '''
|
||||
int main (int argc, char ** argv) {
|
||||
__asm__("@0@");
|
||||
return 0;
|
||||
}'''
|
||||
|
||||
asm_optimization = []
|
||||
inline_optimization = []
|
||||
if not opt_asm.disabled()
|
||||
# Currently we only have inline asm for fixed-point
|
||||
if host_cpu_family == 'arm' and opt_fixed_point
|
||||
opus_conf.set('OPUS_ARM_ASM', true)
|
||||
|
||||
# Check if compiler supports gcc-style inline assembly
|
||||
if cc.compiles('''#ifdef __GNUC_MINOR__
|
||||
#if (__GNUC__ * 1000 + __GNUC_MINOR__) < 3004
|
||||
#error GCC before 3.4 has critical bugs compiling inline assembly
|
||||
#endif
|
||||
#endif
|
||||
__asm__ (""::)''',
|
||||
name : 'compiler supports gcc-style inline assembly')
|
||||
|
||||
opus_conf.set('OPUS_ARM_INLINE_ASM', 1)
|
||||
|
||||
# AS_ASM_ARM_EDSP
|
||||
if cc.compiles(asm_tmpl.format('qadd r3,r3,r3'),
|
||||
name : 'assembler supports EDSP instructions on ARM')
|
||||
opus_conf.set('OPUS_ARM_INLINE_EDSP', 1)
|
||||
inline_optimization += ['ESDP']
|
||||
endif
|
||||
|
||||
# AS_ASM_ARM_MEDIA
|
||||
if cc.compiles(asm_tmpl.format('shadd8 r3,r3,r3'),
|
||||
name : 'assembler supports ARMv6 media instructions on ARM')
|
||||
opus_conf.set('OPUS_ARM_INLINE_MEDIA', 1)
|
||||
inline_optimization += ['Media']
|
||||
endif
|
||||
|
||||
# AS_ASM_ARM_NEON
|
||||
if cc.compiles(asm_tmpl.format('vorr d0,d0,d0'),
|
||||
name : 'assembler supports NEON instructions on ARM')
|
||||
opus_conf.set('OPUS_ARM_INLINE_NEON', 1)
|
||||
inline_optimization += ['NEON']
|
||||
endif
|
||||
endif
|
||||
|
||||
# We need Perl to translate RVCT-syntax asm to gas syntax
|
||||
perl = find_program('perl', required: get_option('asm'))
|
||||
if perl.found()
|
||||
opus_arm_external_asm = true
|
||||
# opus_arm_presume_* mean we can and will use those instructions
|
||||
# directly without doing runtime CPU detection.
|
||||
# opus_arm_may_have_* mean we can emit those instructions, but we can
|
||||
# only use them after runtime detection.
|
||||
# The same rules apply for x86 assembly and intrinsics.
|
||||
|
||||
opus_arm_may_have_edsp = opus_conf.has('OPUS_ARM_INLINE_EDSP')
|
||||
opus_arm_presume_edsp = opus_arm_may_have_edsp and opus_can_presume_simd
|
||||
|
||||
opus_arm_may_have_media = opus_conf.has('OPUS_ARM_INLINE_MEDIA')
|
||||
opus_arm_presume_media = opus_arm_may_have_media and opus_can_presume_simd
|
||||
|
||||
opus_arm_may_have_neon = opus_conf.has('OPUS_ARM_INLINE_NEON')
|
||||
opus_arm_presume_neon = opus_arm_may_have_neon and opus_can_presume_simd
|
||||
|
||||
if not opt_rtcd.disabled()
|
||||
if not opus_arm_may_have_edsp
|
||||
message('Trying to force-enable armv5e EDSP instructions...')
|
||||
# AS_ASM_ARM_EDSP_FORCE
|
||||
opus_arm_may_have_edsp = cc.compiles(asm_tmpl.format('.arch armv5te\n.object_arch armv4t\nqadd r3,r3,r3'),
|
||||
name : 'Assembler supports EDSP instructions on ARM (forced)')
|
||||
endif
|
||||
if not opus_arm_may_have_media
|
||||
message('Trying to force-enable ARMv6 media instructions...')
|
||||
opus_arm_may_have_media = cc.compiles(asm_tmpl.format('.arch armv6\n.object_arch armv4t\nshadd8 r3,r3,r3'),
|
||||
name : 'Assembler supports ARMv6 media instructions on ARM (forced)')
|
||||
endif
|
||||
if not opus_arm_may_have_neon
|
||||
message('Trying to force-enable NEON instructions...')
|
||||
opus_arm_may_have_neon = cc.compiles(asm_tmpl.format('.arch armv7-a\n.fpu neon\n.object_arch armv4t\nvorr d0,d0,d0'),
|
||||
name : 'Assembler supports NEON instructions on ARM (forced)')
|
||||
endif
|
||||
endif
|
||||
|
||||
if opus_arm_may_have_edsp
|
||||
opus_conf.set('OPUS_ARM_MAY_HAVE_EDSP', 1)
|
||||
if opus_arm_presume_edsp
|
||||
opus_conf.set('OPUS_ARM_PRESUME_EDSP', 1)
|
||||
asm_optimization += ['EDSP']
|
||||
else
|
||||
rtcd_support += ['EDSP']
|
||||
endif
|
||||
endif
|
||||
if opus_arm_may_have_media
|
||||
opus_conf.set('OPUS_ARM_MAY_HAVE_MEDIA', 1)
|
||||
if opus_arm_presume_media
|
||||
opus_conf.set('OPUS_ARM_PRESUME_MEDIA', 1)
|
||||
asm_optimization += ['Media']
|
||||
else
|
||||
rtcd_support += ['Media']
|
||||
endif
|
||||
endif
|
||||
if opus_arm_may_have_neon
|
||||
opus_conf.set('OPUS_ARM_MAY_HAVE_NEON', 1)
|
||||
if opus_arm_presume_neon
|
||||
opus_conf.set('OPUS_ARM_PRESUME_NEON', 1)
|
||||
asm_optimization += ['NEON']
|
||||
else
|
||||
rtcd_support += ['NEON']
|
||||
endif
|
||||
endif
|
||||
|
||||
if cc.get_define('__APPLE__')
|
||||
arm2gnu_args = ['--apple']
|
||||
else
|
||||
arm2gnu_args = []
|
||||
endif
|
||||
endif # found perl
|
||||
else # arm + enable fixed point
|
||||
if opt_asm.enabled()
|
||||
error('asm option is enabled, but no assembly support for ' + host_cpu_family)
|
||||
endif
|
||||
endif
|
||||
endif # enable asm
|
||||
|
||||
# Check whether we require assembly and we support assembly on this arch,
|
||||
# but none were detected. Can happen because of incorrect compiler flags, such
|
||||
# as missing -mfloat-abi=softfp on ARM32 softfp architectures.
|
||||
if opt_asm.enabled() and (asm_optimization.length() + inline_optimization.length()) == 0
|
||||
error('asm option was enabled, but no assembly support was detected')
|
||||
endif
|
||||
|
||||
# XXX: NEON has hardfp vs softfp compiler configuration issues
|
||||
# When targeting ARM32 softfp, we sometimes need to explicitly pass
|
||||
# -mfloat-abi=softfp to enable NEON. F.ex., on Android. It should
|
||||
# be set in the cross file.
|
||||
arm_neon_intr_link_args = ['-mfpu=neon']
|
||||
|
||||
have_sse = false
|
||||
have_sse2 = false
|
||||
have_sse4_1 = false
|
||||
have_avx = false # no avx opus code yet
|
||||
have_neon_intr = false
|
||||
|
||||
intrinsics_support = []
|
||||
if not opt_intrinsics.disabled()
|
||||
if host_cpu_family in ['arm', 'aarch64']
|
||||
# Check for ARMv7/AArch64 neon intrinsics
|
||||
intrin_check = '''
|
||||
#include <arm_neon.h>
|
||||
int main (void) {
|
||||
static float32x4_t A0, A1, SUMM;
|
||||
SUMM = vmlaq_f32(SUMM, A0, A1);
|
||||
return (int)vgetq_lane_f32(SUMM, 0);
|
||||
}'''
|
||||
intrin_name = 'ARMv7/AArch64 NEON'
|
||||
if cc.links(intrin_check,
|
||||
name: 'compiler supports @0@ intrinsics'.format(intrin_name))
|
||||
opus_arm_presume_neon_intr = opus_can_presume_simd
|
||||
opus_arm_may_have_neon_intr = true
|
||||
else
|
||||
opus_arm_presume_neon_intr = false
|
||||
if cc.links(intrin_check,
|
||||
args: arm_neon_intr_link_args,
|
||||
name: 'compiler supports @0@ intrinsics with @1@'.format(intrin_name, ' '.join(arm_neon_intr_link_args)))
|
||||
opus_arm_may_have_neon_intr = true
|
||||
else
|
||||
opus_arm_may_have_neon_intr = false
|
||||
endif
|
||||
endif
|
||||
|
||||
if opus_arm_may_have_neon_intr
|
||||
have_neon_intr = true
|
||||
intrinsics_support += [intrin_name]
|
||||
opus_conf.set('OPUS_ARM_MAY_HAVE_NEON_INTR', 1)
|
||||
if opus_arm_presume_neon_intr
|
||||
opus_conf.set('OPUS_ARM_PRESUME_NEON_INTR', 1)
|
||||
else
|
||||
rtcd_support += [intrin_name]
|
||||
opus_neon_intr_args = arm_neon_intr_link_args
|
||||
endif
|
||||
else
|
||||
message('Compiler does not support @0@ intrinsics'.format(intrin_name))
|
||||
endif
|
||||
|
||||
# Check for aarch64 neon intrinsics
|
||||
intrin_check = '''
|
||||
#include <arm_neon.h>
|
||||
int main (void) {
|
||||
static int32_t IN;
|
||||
static int16_t OUT;
|
||||
OUT = vqmovns_s32(IN);
|
||||
}'''
|
||||
intrin_name = 'AArch64 NEON'
|
||||
if cc.links(intrin_check,
|
||||
name: 'compiler supports @0@ intrinsics'.format(intrin_name))
|
||||
opus_arm_presume_aarch64_neon_intr = opus_can_presume_simd
|
||||
opus_arm_may_have_aarch64_neon_intr = true
|
||||
else
|
||||
opus_arm_presume_aarch64_neon_intr = false
|
||||
if cc.links(intrin_check,
|
||||
args: arm_neon_intr_link_args,
|
||||
name: 'compiler supports @0@ intrinsics with @1@'.format(intrin_name, ' '.join(arm_neon_intr_link_args)))
|
||||
opus_arm_may_have_aarch64_neon_intr = true
|
||||
else
|
||||
opus_arm_may_have_aarch64_neon_intr = false
|
||||
endif
|
||||
endif
|
||||
|
||||
if opus_arm_may_have_aarch64_neon_intr
|
||||
intrinsics_support += [intrin_name]
|
||||
opus_conf.set('OPUS_X86_MAY_HAVE_AARCH64_NEON_INTR', 1)
|
||||
if opus_arm_presume_aarch64_neon_intr
|
||||
opus_conf.set('OPUS_X86_PRESUME_AARCH64_NEON_INTR', 1)
|
||||
endif
|
||||
else
|
||||
message('Compiler does not support @0@ intrinsics'.format(intrin_name))
|
||||
endif
|
||||
elif host_cpu_family in ['x86', 'x86_64']
|
||||
# XXX: allow external override/specification of the flags
|
||||
x86_intrinsics = [
|
||||
[ 'SSE', 'xmmintrin.h', '__m128', '_mm_setzero_ps()', ['-msse'] ],
|
||||
[ 'SSE2', 'emmintrin.h', '__m128i', '_mm_setzero_si128()', ['-msse2'] ],
|
||||
[ 'SSE4.1', 'smmintrin.h', '__m128i', '_mm_setzero_si128(); mtest = _mm_cmpeq_epi64(mtest, mtest)', ['-msse4.1'] ],
|
||||
[ 'AVX', 'immintrin.h', '__m256', '_mm256_setzero_ps()', ['-mavx'] ],
|
||||
]
|
||||
|
||||
foreach intrin : x86_intrinsics
|
||||
intrin_check = '''#include <@0@>
|
||||
int main (int argc, char ** argv) {
|
||||
static @1@ mtest;
|
||||
mtest = @2@;
|
||||
return *((unsigned char *) &mtest) != 0;
|
||||
}'''.format(intrin[1],intrin[2],intrin[3])
|
||||
intrin_name = intrin[0]
|
||||
# Intrinsics arguments are not available with MSVC-like compilers
|
||||
intrin_args = cc.get_argument_syntax() == 'msvc' ? [] : intrin[4]
|
||||
if cc.links(intrin_check, name : 'compiler supports @0@ intrinsics'.format(intrin_name))
|
||||
may_have_intrin = true
|
||||
presume_intrin = opus_can_presume_simd
|
||||
elif intrin_args.length() > 0
|
||||
presume_intrin = false
|
||||
if cc.links(intrin_check,
|
||||
args : intrin_args,
|
||||
name : 'compiler supports @0@ intrinsics with @1@'.format(intrin_name, ' '.join(intrin_args)))
|
||||
may_have_intrin = true
|
||||
else
|
||||
may_have_intrin = false
|
||||
endif
|
||||
endif
|
||||
if may_have_intrin
|
||||
intrinsics_support += [intrin_name]
|
||||
intrin_lower_name = intrin_name.to_lower().underscorify()
|
||||
set_variable('have_' + intrin_lower_name, true)
|
||||
opus_conf.set('OPUS_X86_MAY_HAVE_' + intrin_name.underscorify(), 1)
|
||||
if presume_intrin
|
||||
opus_conf.set('OPUS_X86_PRESUME_' + intrin_name.underscorify(), 1)
|
||||
else
|
||||
rtcd_support += [intrin_name]
|
||||
set_variable('opus_@0@_args'.format(intrin_lower_name), intrin_args)
|
||||
endif
|
||||
else
|
||||
message('Compiler does not support @0@ intrinsics'.format(intrin_name))
|
||||
endif
|
||||
endforeach
|
||||
|
||||
if not opt_rtcd.disabled()
|
||||
get_cpuid_by_asm = false
|
||||
cpuid_asm_code = '''
|
||||
#include <stdio.h>
|
||||
int main (int argc, char ** argv) {
|
||||
unsigned int CPUInfo0;
|
||||
unsigned int CPUInfo1;
|
||||
unsigned int CPUInfo2;
|
||||
unsigned int CPUInfo3;
|
||||
unsigned int InfoType;
|
||||
#if defined(__i386__) && defined(__PIC__)
|
||||
__asm__ __volatile__ (
|
||||
"xchg %%ebx, %1\n"
|
||||
"cpuid\n"
|
||||
"xchg %%ebx, %1\n":
|
||||
"=a" (CPUInfo0),
|
||||
"=r" (CPUInfo1),
|
||||
"=c" (CPUInfo2),
|
||||
"=d" (CPUInfo3) :
|
||||
"a" (InfoType), "c" (0)
|
||||
);
|
||||
#else
|
||||
__asm__ __volatile__ (
|
||||
"cpuid":
|
||||
"=a" (CPUInfo0),
|
||||
"=b" (CPUInfo1),
|
||||
"=c" (CPUInfo2),
|
||||
"=d" (CPUInfo3) :
|
||||
"a" (InfoType), "c" (0)
|
||||
);
|
||||
#endif
|
||||
return 0;
|
||||
}'''
|
||||
cpuid_c_code = '''
|
||||
#include <cpuid.h>
|
||||
int main (int argc, char ** argv) {
|
||||
unsigned int CPUInfo0;
|
||||
unsigned int CPUInfo1;
|
||||
unsigned int CPUInfo2;
|
||||
unsigned int CPUInfo3;
|
||||
unsigned int InfoType;
|
||||
__get_cpuid(InfoType, &CPUInfo0, &CPUInfo1, &CPUInfo2, &CPUInfo3);
|
||||
return 0;
|
||||
}'''
|
||||
cpuid_msvc_code = '''
|
||||
#include <intrin.h>
|
||||
int main (void) {
|
||||
int CPUInfo, InfoType;
|
||||
__cpuid(&CPUInfo, InfoType);
|
||||
}'''
|
||||
if cc.links(cpuid_asm_code, name : 'Get X86 CPU info via inline assembly')
|
||||
opus_conf.set('CPU_INFO_BY_ASM', 1)
|
||||
elif cc.links(cpuid_c_code, name : 'Get X86 CPU info via C method')
|
||||
opus_conf.set('CPU_INFO_BY_C', 1)
|
||||
elif cc.get_define('_MSC_VER') != '' and cc.links(cpuid_msvc_code)
|
||||
message('Getting X86 CPU info via __cpuid')
|
||||
else
|
||||
if opt_intrinsics.enabled() and opt_rtcd.enabled()
|
||||
error('intrinsics and rtcd options are enabled, but no Get CPU Info method detected')
|
||||
endif
|
||||
warning('Get CPU Info method not detected, no rtcd for intrinsics')
|
||||
endif
|
||||
endif # opt_rtcd
|
||||
else
|
||||
if opt_intrinsics.enabled()
|
||||
error('intrinsics option enabled, but no intrinsics support for ' + host_machine.get_cpu())
|
||||
endif
|
||||
warning('No intrinsics support for ' + host_machine.get_cpu())
|
||||
endif
|
||||
endif
|
||||
|
||||
# Check whether we require intrinsics and we support intrinsics on this arch,
|
||||
# but none were detected. Can happen because of incorrect compiler flags, such
|
||||
# as missing -mfloat-abi=softfp on ARM32 softfp architectures.
|
||||
if opt_intrinsics.enabled() and intrinsics_support.length() == 0
|
||||
error('intrinsics option was enabled, but none were detected')
|
||||
endif
|
||||
|
||||
if opt_rtcd.disabled()
|
||||
rtcd_support = 'disabled'
|
||||
else
|
||||
if rtcd_support.length() > 0
|
||||
opus_conf.set('OPUS_HAVE_RTCD', 1)
|
||||
else
|
||||
if intrinsics_support.length() == 0
|
||||
rtcd_support = 'none'
|
||||
if opt_rtcd.enabled()
|
||||
error('rtcd option is enabled, but no support for intrinsics or assembly is available')
|
||||
endif
|
||||
else
|
||||
rtcd_support = 'not needed'
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# extract source file lists from .mk files
|
||||
mk_files = ['silk_sources.mk', 'opus_headers.mk', 'opus_sources.mk', 'silk_headers.mk', 'celt_sources.mk', 'celt_headers.mk']
|
||||
lines = run_command('meson/read-sources-list.py', mk_files, check: true).stdout().strip().split('\n')
|
||||
sources = {}
|
||||
foreach l : lines
|
||||
a = l.split(' = ')
|
||||
var_name = a[0]
|
||||
file_list = a[1].split()
|
||||
sources += {var_name: files(file_list)}
|
||||
endforeach
|
||||
|
||||
subdir('include')
|
||||
subdir('silk')
|
||||
subdir('celt')
|
||||
subdir('src')
|
||||
|
||||
configure_file(output: 'config.h', configuration: opus_conf)
|
||||
|
||||
if not opt_tests.disabled()
|
||||
subdir('celt/tests')
|
||||
subdir('silk/tests')
|
||||
subdir('tests')
|
||||
endif
|
||||
|
||||
# pkg-config files (not using pkg module so we can use the existing .pc.in file)
|
||||
pkgconf = configuration_data()
|
||||
|
||||
pkgconf.set('prefix', join_paths(get_option('prefix')))
|
||||
pkgconf.set('exec_prefix', '${prefix}')
|
||||
pkgconf.set('libdir', '${prefix}/@0@'.format(get_option('libdir')))
|
||||
pkgconf.set('includedir', '${prefix}/@0@'.format(get_option('includedir')))
|
||||
pkgconf.set('VERSION', opus_version)
|
||||
pkgconf.set('PC_BUILD', pc_build)
|
||||
pkgconf.set('LIBM', libm.found() ? '-lm' : '')
|
||||
|
||||
pkg_install_dir = '@0@/pkgconfig'.format(get_option('libdir'))
|
||||
|
||||
configure_file(input : 'opus.pc.in',
|
||||
output : 'opus.pc',
|
||||
configuration : pkgconf,
|
||||
install_dir : pkg_install_dir)
|
||||
|
||||
# The uninstalled one has hardcoded libtool + static lib stuff, skip it for now
|
||||
#configure_file(input : 'opus-uninstalled.pc.in',
|
||||
# output : 'opus-uninstalled.pc',
|
||||
# configuration : pkgconf,
|
||||
# install : false)
|
||||
|
||||
doxygen = find_program('doxygen', required: get_option('docs'))
|
||||
if doxygen.found()
|
||||
subdir('doc')
|
||||
endif
|
||||
|
||||
summary(
|
||||
{
|
||||
'C99 var arrays': opus_conf.has('VAR_ARRAYS'),
|
||||
'C99 lrintf': opus_conf.has('HAVE_LRINTF'),
|
||||
'Use alloca': msg_use_alloca,
|
||||
},
|
||||
section: 'Compiler support',
|
||||
bool_yn: true,
|
||||
list_sep: ', ',
|
||||
)
|
||||
|
||||
# Parse optimization status
|
||||
foreach status : [['inline_optimization', opt_asm],
|
||||
['asm_optimization', opt_asm],
|
||||
['intrinsics_support', opt_intrinsics]]
|
||||
res = status[0]
|
||||
opt = status[1]
|
||||
resval = get_variable(res)
|
||||
if opt.disabled()
|
||||
set_variable(res, 'disabled')
|
||||
elif resval.length() == 0
|
||||
if host_cpu_family not in ['arm', 'aarch64', 'x86', 'x86_64']
|
||||
set_variable(res, 'No optimizations for your platform, please send patches')
|
||||
else
|
||||
set_variable(res, 'none')
|
||||
endif
|
||||
endif
|
||||
endforeach
|
||||
|
||||
summary(
|
||||
{
|
||||
'Floating point support': not opt_fixed_point,
|
||||
'Fast float approximations': opt_float_approx,
|
||||
'Fixed point debugging': opt_fixed_point_debug,
|
||||
'Inline assembly optimizations': inline_optimization,
|
||||
'External assembly optimizations': asm_optimization,
|
||||
'Intrinsics optimizations': intrinsics_support,
|
||||
'Run-time CPU detection': rtcd_support,
|
||||
},
|
||||
section: 'Optimizations',
|
||||
bool_yn: true,
|
||||
list_sep: ', ',
|
||||
)
|
||||
summary(
|
||||
{
|
||||
'Custom modes': opt_custom_modes,
|
||||
'Assertions': opt_assertions,
|
||||
'Hardening': opt_hardening,
|
||||
'Fuzzing': opt_fuzzing,
|
||||
'Check ASM': opt_check_asm,
|
||||
'API documentation': doxygen.found(),
|
||||
'Extra programs': not extra_programs.disabled(),
|
||||
'Tests': not opt_tests.disabled(),
|
||||
},
|
||||
section: 'General configuration',
|
||||
bool_yn: true,
|
||||
list_sep: ', ',
|
||||
)
|
86
meson/get-version.py
Executable file
86
meson/get-version.py
Executable file
|
@ -0,0 +1,86 @@
|
|||
#!/usr/bin/env python3
|
||||
#
|
||||
# Opus get-version.py
|
||||
#
|
||||
# Extracts versions for build:
|
||||
# - Opus package version based on 'git describe' or $srcroot/package_version
|
||||
# - libtool version based on configure.ac
|
||||
# - macos lib version based on configure.ac
|
||||
#
|
||||
# Usage:
|
||||
# get-version.py [--package-version | --libtool-version | --darwin-version]
|
||||
import argparse
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
|
||||
if __name__ == '__main__':
|
||||
arg_parser = argparse.ArgumentParser(description='Extract Opus package version or libtool version')
|
||||
group = arg_parser.add_mutually_exclusive_group(required=True)
|
||||
group.add_argument('--libtool-version', action='store_true')
|
||||
group.add_argument('--package-version', action='store_true')
|
||||
group.add_argument('--darwin-version', action='store_true')
|
||||
args = arg_parser.parse_args()
|
||||
|
||||
srcroot = os.path.normpath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
|
||||
# package version
|
||||
if args.package_version:
|
||||
package_version = None
|
||||
|
||||
# check if git checkout
|
||||
git_dir = os.path.join(srcroot, '.git')
|
||||
is_git = os.path.isdir(git_dir)
|
||||
have_git = shutil.which('git') is not None
|
||||
|
||||
if is_git and have_git:
|
||||
git_cmd = subprocess.run(['git', '--git-dir=' + git_dir, 'describe', 'HEAD'], stdout=subprocess.PIPE)
|
||||
if git_cmd.returncode:
|
||||
print('ERROR: Could not extract package version via `git describe` in', srcroot, file=sys.stderr)
|
||||
sys.exit(-1)
|
||||
package_version = git_cmd.stdout.decode('ascii').strip().lstrip('v')
|
||||
else:
|
||||
with open(os.path.join(srcroot, 'package_version'), 'r') as f:
|
||||
for line in f:
|
||||
if line.startswith('PACKAGE_VERSION="'):
|
||||
package_version = line[17:].strip().lstrip('v').rstrip('"')
|
||||
if package_version:
|
||||
break
|
||||
|
||||
if not package_version:
|
||||
print('ERROR: Could not extract package version from package_version file in', srcroot, file=sys.stderr)
|
||||
sys.exit(-1)
|
||||
|
||||
print(package_version)
|
||||
sys.exit(0)
|
||||
|
||||
# libtool version + darwin version
|
||||
elif args.libtool_version or args.darwin_version:
|
||||
opus_lt_cur = None
|
||||
opus_lt_rev = None
|
||||
opus_lt_age = None
|
||||
|
||||
with open(os.path.join(srcroot, 'configure.ac'), 'r') as f:
|
||||
for line in f:
|
||||
if line.strip().startswith('OPUS_LT_CURRENT='):
|
||||
opus_lt_cur = line[16:].strip()
|
||||
elif line.strip().startswith('OPUS_LT_REVISION='):
|
||||
opus_lt_rev = line[17:].strip()
|
||||
elif line.strip().startswith('OPUS_LT_AGE='):
|
||||
opus_lt_age = line[12:].strip()
|
||||
|
||||
if opus_lt_cur and opus_lt_rev and opus_lt_age:
|
||||
opus_lt_cur = int(opus_lt_cur)
|
||||
opus_lt_rev = int(opus_lt_rev)
|
||||
opus_lt_age = int(opus_lt_age)
|
||||
if args.libtool_version:
|
||||
print('{}.{}.{}'.format(opus_lt_cur - opus_lt_age, opus_lt_age, opus_lt_rev))
|
||||
elif args.darwin_version:
|
||||
print('{}.{}.{}'.format(opus_lt_cur + 1, 0, 0))
|
||||
sys.exit(0)
|
||||
else:
|
||||
print('ERROR: Could not extract libtool version from configure.ac file in', srcroot, file=sys.stderr)
|
||||
sys.exit(-1)
|
||||
else:
|
||||
sys.exit(-1)
|
28
meson/read-sources-list.py
Executable file
28
meson/read-sources-list.py
Executable file
|
@ -0,0 +1,28 @@
|
|||
#!/usr/bin/env python3
|
||||
#
|
||||
# opus/read-sources-list.py
|
||||
#
|
||||
# Parses .mk files and extracts list of source files.
|
||||
# Prints one line per source file list, with filenames space-separated.
|
||||
|
||||
import sys
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
sys.exit('Usage: {} sources_foo.mk [sources_bar.mk...]'.format(sys.argv[0]))
|
||||
|
||||
for input_fn in sys.argv[1:]:
|
||||
with open(input_fn, 'r', encoding='utf8') as f:
|
||||
text = f.read()
|
||||
text = text.replace('\\\n', '')
|
||||
|
||||
# Remove empty lines
|
||||
lines = [line for line in text.split('\n') if line.strip()]
|
||||
|
||||
# Print SOURCES_XYZ = file1.c file2.c
|
||||
for line in lines:
|
||||
values = line.strip().split('=', maxsplit=2)
|
||||
if len(values) != 2:
|
||||
raise RuntimeError('Unable to parse line "{}" from file "{}"'.format(line, input_fn))
|
||||
var, files = values
|
||||
sources_list = [f for f in files.split(' ') if f]
|
||||
print(var.strip(), '=', ' '.join(sources_list))
|
22
meson_options.txt
Normal file
22
meson_options.txt
Normal file
|
@ -0,0 +1,22 @@
|
|||
# Optimizations
|
||||
option('fixed-point', type : 'boolean', value : false, description : 'Compile without floating point (for machines without a fast enough FPU')
|
||||
option('fixed-point-debug', type : 'boolean', value : false, description : 'Debug fixed-point implementation')
|
||||
option('float-api', type : 'boolean', value : true, description : 'Compile with or without the floating point API (for machines with no float library')
|
||||
option('float-approx', type : 'boolean', value : false, description : 'Enable fast approximations for floating point (not supported on all platforms)')
|
||||
option('rtcd', type : 'feature', value : 'auto', description : 'Run-time CPU capabilities detection')
|
||||
option('asm', type : 'feature', value : 'auto', description : 'Assembly optimizations for ARM (fixed-point)')
|
||||
option('intrinsics', type : 'feature', value : 'auto', description : 'Intrinsics optimizations for ARM NEON or x86')
|
||||
|
||||
option('custom-modes', type : 'boolean', value : false, description : 'Enable non-Opus modes, e.g. 44.1 kHz & 2^n frames')
|
||||
option('extra-programs', type : 'feature', value : 'auto', description : 'Extra programs (demo and tests)')
|
||||
option('assertions', type : 'boolean', value : false, description : 'Additional software error checking')
|
||||
option('hardening', type : 'boolean', value : true, description : 'Run-time checks that are cheap and safe for use in production')
|
||||
option('fuzzing', type : 'boolean', value : false, description : 'Causes the encoder to make random decisions')
|
||||
option('check-asm', type : 'boolean', value : false, description : 'Run bit-exactness checks between optimized and c implementations')
|
||||
|
||||
# common feature options
|
||||
option('tests', type : 'feature', value : 'auto', description : 'Build tests')
|
||||
option('docs', type: 'feature', value: 'auto', description: 'Build API documentation')
|
||||
|
||||
# other options
|
||||
option('docdir', type: 'string', value: 'doc/opus', description: 'Directory to install documentation into (default: DATADIR/doc/opus')
|
53
silk/meson.build
Normal file
53
silk/meson.build
Normal file
|
@ -0,0 +1,53 @@
|
|||
silk_sources = sources['SILK_SOURCES']
|
||||
|
||||
silk_sources_sse4_1 = sources['SILK_SOURCES_SSE4_1']
|
||||
|
||||
silk_sources_neon_intr = sources['SILK_SOURCES_ARM_NEON_INTR']
|
||||
|
||||
silk_sources_fixed_neon_intr = sources['SILK_SOURCES_FIXED_ARM_NEON_INTR']
|
||||
|
||||
silk_sources_fixed = sources['SILK_SOURCES_FIXED']
|
||||
|
||||
silk_sources_fixed_sse4_1 = sources['SILK_SOURCES_FIXED_SSE4_1']
|
||||
|
||||
silk_sources_float = sources['SILK_SOURCES_FLOAT']
|
||||
|
||||
if opt_fixed_point
|
||||
silk_sources += silk_sources_fixed
|
||||
else
|
||||
silk_sources += silk_sources_float
|
||||
endif
|
||||
|
||||
silk_includes = [opus_includes, include_directories('float', 'fixed')]
|
||||
silk_static_libs = []
|
||||
|
||||
foreach intr_name : ['sse4_1', 'neon_intr']
|
||||
have_intr = get_variable('have_' + intr_name)
|
||||
if not have_intr
|
||||
continue
|
||||
endif
|
||||
|
||||
intr_sources = get_variable('silk_sources_' + intr_name)
|
||||
if opt_fixed_point
|
||||
intr_sources += get_variable('silk_sources_fixed_' + intr_name)
|
||||
endif
|
||||
|
||||
intr_args = get_variable('opus_@0@_args'.format(intr_name), [])
|
||||
silk_static_libs += static_library('silk_' + intr_name, intr_sources,
|
||||
c_args: intr_args,
|
||||
include_directories: silk_includes,
|
||||
install: false)
|
||||
endforeach
|
||||
|
||||
silk_c_args = []
|
||||
if host_machine.system() == 'windows'
|
||||
silk_c_args += ['-DDLL_EXPORT']
|
||||
endif
|
||||
|
||||
silk_lib = static_library('opus-silk',
|
||||
silk_sources,
|
||||
c_args: silk_c_args,
|
||||
include_directories: silk_includes,
|
||||
link_whole: silk_static_libs,
|
||||
dependencies: libm,
|
||||
install: false)
|
8
silk/tests/meson.build
Normal file
8
silk/tests/meson.build
Normal file
|
@ -0,0 +1,8 @@
|
|||
exe = executable('test_unit_LPC_inv_pred_gain',
|
||||
'test_unit_LPC_inv_pred_gain.c', '../LPC_inv_pred_gain.c',
|
||||
include_directories: opus_includes,
|
||||
link_with: [celt_lib, celt_static_libs, silk_lib, silk_static_libs],
|
||||
dependencies: libm,
|
||||
install: false)
|
||||
|
||||
test(test_name, exe)
|
45
src/meson.build
Normal file
45
src/meson.build
Normal file
|
@ -0,0 +1,45 @@
|
|||
opus_sources = sources['OPUS_SOURCES']
|
||||
|
||||
opus_sources_float = sources['OPUS_SOURCES_FLOAT']
|
||||
|
||||
if not disable_float_api
|
||||
opus_sources += opus_sources_float
|
||||
endif
|
||||
|
||||
opus_lib_c_args = []
|
||||
if host_machine.system() == 'windows'
|
||||
opus_lib_c_args += ['-DDLL_EXPORT']
|
||||
endif
|
||||
|
||||
opus_lib = library('opus',
|
||||
opus_sources,
|
||||
version: libversion,
|
||||
darwin_versions: macosversion,
|
||||
c_args: opus_lib_c_args,
|
||||
include_directories: opus_includes,
|
||||
link_with: [celt_lib, silk_lib],
|
||||
dependencies: libm,
|
||||
install: true)
|
||||
|
||||
opus_dep = declare_dependency(link_with: opus_lib,
|
||||
include_directories: opus_public_includes)
|
||||
|
||||
# Extra uninstalled Opus programs
|
||||
if not extra_programs.disabled()
|
||||
foreach prog : ['opus_compare', 'opus_demo', 'repacketizer_demo']
|
||||
executable(prog, '@0@.c'.format(prog),
|
||||
include_directories: opus_includes,
|
||||
link_with: opus_lib,
|
||||
dependencies: libm,
|
||||
install: false)
|
||||
endforeach
|
||||
|
||||
if opt_custom_modes
|
||||
executable('opus_custom_demo', '../celt/opus_custom_demo.c',
|
||||
include_directories: opus_includes,
|
||||
link_with: opus_lib,
|
||||
dependencies: libm,
|
||||
install: false)
|
||||
endif
|
||||
|
||||
endif
|
34
tests/meson.build
Normal file
34
tests/meson.build
Normal file
|
@ -0,0 +1,34 @@
|
|||
# Tests that link to libopus
|
||||
opus_tests = [
|
||||
['test_opus_api'],
|
||||
['test_opus_decode', [], 60],
|
||||
['test_opus_encode', 'opus_encode_regressions.c', 120],
|
||||
['test_opus_padding'],
|
||||
['test_opus_projection'],
|
||||
]
|
||||
|
||||
foreach t : opus_tests
|
||||
test_name = t.get(0)
|
||||
extra_srcs = t.get(1, [])
|
||||
|
||||
test_kwargs = {}
|
||||
if t.length() > 2
|
||||
test_kwargs += {'timeout': t[2]}
|
||||
endif
|
||||
|
||||
exe_kwargs = {}
|
||||
# This test uses private symbols
|
||||
if test_name == 'test_opus_projection'
|
||||
exe_kwargs = {
|
||||
'link_with': [celt_lib, silk_lib],
|
||||
'objects': opus_lib.extract_all_objects(),
|
||||
}
|
||||
endif
|
||||
|
||||
exe = executable(test_name, '@0@.c'.format(test_name), extra_srcs,
|
||||
include_directories: opus_includes,
|
||||
dependencies: [libm, opus_dep],
|
||||
install: false,
|
||||
kwargs: exe_kwargs)
|
||||
test(test_name, exe, kwargs: test_kwargs)
|
||||
endforeach
|
Loading…
Add table
Add a link
Reference in a new issue