if(__opus_functions)
return()
endif()
set(__opus_functions INCLUDED)
function(get_library_version OPUS_LIBRARY_VERSION OPUS_LIBRARY_VERSION_MAJOR)
file(STRINGS configure.ac opus_lt_current_string
LIMIT_COUNT 1
REGEX "OPUS_LT_CURRENT=")
string(REGEX MATCH
"OPUS_LT_CURRENT=([0-9]*)"
_
${opus_lt_current_string})
set(OPUS_LT_CURRENT ${CMAKE_MATCH_1})
file(STRINGS configure.ac opus_lt_revision_string
LIMIT_COUNT 1
REGEX "OPUS_LT_REVISION=")
string(REGEX MATCH
"OPUS_LT_REVISION=([0-9]*)"
_
${opus_lt_revision_string})
set(OPUS_LT_REVISION ${CMAKE_MATCH_1})
file(STRINGS configure.ac opus_lt_age_string
LIMIT_COUNT 1
REGEX "OPUS_LT_AGE=")
string(REGEX MATCH
"OPUS_LT_AGE=([0-9]*)"
_
${opus_lt_age_string})
set(OPUS_LT_AGE ${CMAKE_MATCH_1})
math(EXPR OPUS_LIBRARY_VERSION_MAJOR "${OPUS_LT_CURRENT} - ${OPUS_LT_AGE}")
set(OPUS_LIBRARY_VERSION_MINOR ${OPUS_LT_AGE})
set(OPUS_LIBRARY_VERSION_PATCH ${OPUS_LT_REVISION})
set(
OPUS_LIBRARY_VERSION
"${OPUS_LIBRARY_VERSION_MAJOR}.${OPUS_LIBRARY_VERSION_MINOR}.${OPUS_LIBRARY_VERSION_PATCH}"
PARENT_SCOPE)
set(OPUS_LIBRARY_VERSION_MAJOR ${OPUS_LIBRARY_VERSION_MAJOR} PARENT_SCOPE)
endfunction()
function(check_flag NAME FLAG)
include(CheckCCompilerFlag)
check_c_compiler_flag(${FLAG} ${NAME}_SUPPORTED)
endfunction()
include(CheckIncludeFile)
# function to check if compiler supports SSE, SSE2, SSE4.1 and AVX if target
# systems may not have SSE support then use OPUS_MAY_HAVE_SSE option if target
# system is guaranteed to have SSE support then OPUS_PRESUME_SSE can be used to
# skip SSE runtime check
function(opus_detect_sse COMPILER_SUPPORT_SIMD)
message(STATUS "Check SIMD support by compiler")
check_include_file(xmmintrin.h HAVE_XMMINTRIN_H) # SSE1
if(HAVE_XMMINTRIN_H)
if(MSVC)
# different arch options for 32 and 64 bit target for MSVC
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
check_flag(SSE1 /arch:SSE)
else()
set(SSE1_SUPPORTED
1
PARENT_SCOPE)
endif()
else()
check_flag(SSE1 -msse)
endif()
else()
set(SSE1_SUPPORTED
0
PARENT_SCOPE)
endif()
check_include_file(emmintrin.h HAVE_EMMINTRIN_H) # SSE2
if(HAVE_EMMINTRIN_H)
if(MSVC)
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
check_flag(SSE2 /arch:SSE2)
else()
set(SSE2_SUPPORTED
1
PARENT_SCOPE)
endif()
else()
check_flag(SSE2 -msse2)
endif()
else()
set(SSE2_SUPPORTED
0
PARENT_SCOPE)
endif()
check_include_file(smmintrin.h HAVE_SMMINTRIN_H) # SSE4.1
if(HAVE_SMMINTRIN_H)
if(MSVC)
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
check_flag(SSE4_1 /arch:SSE2) # SSE2 and above
else()
set(SSE4_1_SUPPORTED
1
PARENT_SCOPE)
endif()
else()
check_flag(SSE4_1 -msse4.1)
endif()
else()
set(SSE4_1_SUPPORTED
0
PARENT_SCOPE)
endif()
check_include_file(immintrin.h HAVE_IMMINTRIN_H) # AVX
if(HAVE_IMMINTRIN_H)
if(MSVC)
check_flag(AVX /arch:AVX)
else()
check_flag(AVX -mavx)
endif()
else()
set(AVX_SUPPORTED
0
PARENT_SCOPE)
endif()
if(SSE1_SUPPORTED OR SSE2_SUPPORTED OR SSE4_1_SUPPORTED OR AVX_SUPPORTED)
set(COMPILER_SUPPORT_SIMD 1 PARENT_SCOPE)
else()
message(STATUS "No SIMD support in compiler")
endif()
endfunction()
function(opus_detect_neon COMPILER_SUPPORT_NEON)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "(arm|aarch64)")
message(STATUS "Check NEON support by compiler")
check_include_file(arm_neon.h HAVE_ARM_NEON_H)
if(HAVE_ARM_NEON_H)
set(COMPILER_SUPPORT_NEON ${HAVE_ARM_NEON_H} PARENT_SCOPE)
endif()
endif()
endfunction()
function(opus_supports_cpu_detection RUNTIME_CPU_CAPABILITY_DETECTION)
set(RUNTIME_CPU_CAPABILITY_DETECTION 0 PARENT_SCOPE)
if(OPUS_CPU_X86 OR OPUS_CPU_X64)
if(MSVC)
check_include_file(intrin.h HAVE_INTRIN_H)
if(HAVE_INTRIN_H)
# if intrin.h is available we assume __cpuid is there
set(RUNTIME_CPU_CAPABILITY_DETECTION 1 PARENT_SCOPE)
endif()
else()
include(CFeatureCheck)
c_feature_check(CPU_INFO_BY_ASM)
set(CPU_INFO_BY_ASM_SUPPORTED ${CPU_INFO_BY_ASM_SUPPORTED} PARENT_SCOPE)
check_include_file(cpuid.h HAVE_CPUID_H)
if(HAVE_CPUID_H)
c_feature_check(CPU_INFO_BY_C)
set(CPU_INFO_BY_C_SUPPORTED ${CPU_INFO_BY_C_SUPPORTED} PARENT_SCOPE)
endif()
if(CPU_INFO_BY_ASM_SUPPORTED OR CPU_INFO_BY_C_SUPPORTED)
set(RUNTIME_CPU_CAPABILITY_DETECTION 1 PARENT_SCOPE)
endif()
endif()
elseif(OPUS_CPU_ARM)
# ARM cpu detection is implemented for Windows and anything
# using a Linux kernel (such as Android).
if (CMAKE_SYSTEM_NAME MATCHES "(Windows|Linux|Android)")
set(RUNTIME_CPU_CAPABILITY_DETECTION 1 PARENT_SCOPE)
endif ()
else()
set(RUNTIME_CPU_CAPABILITY_DETECTION 0 PARENT_SCOPE)
endif()
endfunction()
function(add_sources_group target group)
target_sources(${target} PRIVATE ${ARGN})
source_group(${group} FILES ${ARGN})
endfunction()
function(get_opus_sources SOURCE_GROUP MAKE_FILE SOURCES)
# read file, each item in list is one group
file(STRINGS ${MAKE_FILE} opus_sources)
# add wildcard for regex match
string(CONCAT SOURCE_GROUP ${SOURCE_GROUP} ".*$")
# find group
foreach(val IN LISTS opus_sources)
if(val MATCHES ${SOURCE_GROUP})
list(LENGTH val list_length)
if(${list_length} EQUAL 1)
# for tests split by '=' and clean up the rest into a list
string(FIND ${val} "=" index)
math(EXPR index "${index} + 1")
string(SUBSTRING ${val}
${index}
-1
sources)
string(REPLACE " "
";"
sources
${sources})
else()
# discard the group
list(REMOVE_AT val 0)
set(sources ${val})
endif()
break()
endif()
endforeach()
list(LENGTH sources list_length)
if(${list_length} LESS 1)
message(
FATAL_ERROR
"No files parsed succesfully from ${SOURCE_GROUP} in ${MAKE_FILE}")
endif()
# remove trailing whitespaces
set(list_var "")
foreach(source ${sources})
string(STRIP "${source}" source)
list(APPEND list_var "${source}")
endforeach()
set(${SOURCES} ${list_var} PARENT_SCOPE)
endfunction()