summaryrefslogtreecommitdiff
path: root/libopus/opus_functions.cmake
diff options
context:
space:
mode:
Diffstat (limited to 'libopus/opus_functions.cmake')
-rw-r--r--libopus/opus_functions.cmake262
1 files changed, 262 insertions, 0 deletions
diff --git a/libopus/opus_functions.cmake b/libopus/opus_functions.cmake
new file mode 100644
index 0000000..fe309c2
--- /dev/null
+++ b/libopus/opus_functions.cmake
@@ -0,0 +1,262 @@
+#[[Cmake helper function to parse source files from make files
+this is to avoid breaking existing make and auto make support
+but still have the option to use CMake with only lists at one place]]
+
+cmake_minimum_required(VERSION 3.1)
+
+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(get_package_version PACKAGE_VERSION)
+ find_package(Git)
+ if(GIT_FOUND)
+ execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags --match "v*"
+ OUTPUT_VARIABLE OPUS_PACKAGE_VERSION)
+ if(OPUS_PACKAGE_VERSION)
+ string(STRIP ${OPUS_PACKAGE_VERSION}, OPUS_PACKAGE_VERSION)
+ string(REPLACE \n
+ ""
+ OPUS_PACKAGE_VERSION
+ ${OPUS_PACKAGE_VERSION})
+ string(REPLACE ,
+ ""
+ OPUS_PACKAGE_VERSION
+ ${OPUS_PACKAGE_VERSION})
+
+ string(SUBSTRING ${OPUS_PACKAGE_VERSION}
+ 1
+ -1
+ OPUS_PACKAGE_VERSION)
+ set(PACKAGE_VERSION ${OPUS_PACKAGE_VERSION} PARENT_SCOPE)
+ return()
+ endif()
+ endif()
+
+ if(EXISTS "${CMAKE_SOURCE_DIR}/package_version")
+ # Not a git repo, lets' try to parse it from package_version file if exists
+ file(STRINGS package_version opus_package_version_string
+ LIMIT_COUNT 1
+ REGEX "PACKAGE_VERSION=")
+ string(REPLACE "PACKAGE_VERSION="
+ ""
+ opus_package_version_string
+ ${opus_package_version_string})
+ string(REPLACE "\""
+ ""
+ opus_package_version_string
+ ${opus_package_version_string})
+ set(PACKAGE_VERSION ${opus_package_version_string} PARENT_SCOPE)
+ return()
+ endif()
+
+ # if all else fails set to 0
+ set(PACKAGE_VERSION 0 PARENT_SCOPE)
+endfunction()
+
+function(check_and_set_flag NAME FLAG)
+ include(CheckCCompilerFlag)
+ check_c_compiler_flag(${FLAG} ${NAME}_SUPPORTED)
+ if(${NAME}_SUPPORTED)
+ add_definitions(${FLAG})
+ endif()
+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_and_set_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_and_set_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_and_set_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_and_set_flag(AVX -mavx)
+ endif()
+ else()
+ set(AVX_SUPPORTED 0 PARENT_SCOPE)
+ endif()
+
+ if(MSVC) # To avoid warning D9025 of overriding compiler options
+ if(AVX_SUPPORTED) # on 64 bit and 32 bits
+ add_definitions(/arch:AVX)
+ elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) # if AVX not supported then set SSE flag
+ if(SSE4_1_SUPPORTED OR SSE2_SUPPORTED)
+ add_definitions(/arch:SSE2)
+ elseif(SSE1_SUPPORTED)
+ add_definitions(/arch:SSE)
+ endif()
+ endif()
+ 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 "(armv7-a|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)
+ if(MSVC)
+ check_include_file(intrin.h HAVE_INTRIN_H)
+ else()
+ check_include_file(cpuid.h HAVE_CPUID_H)
+ endif()
+ if(HAVE_INTRIN_H OR HAVE_CPUID_H)
+ set(RUNTIME_CPU_CAPABILITY_DETECTION 1 PARENT_SCOPE)
+ 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()