1if(__opus_functions) 2 return() 3endif() 4set(__opus_functions INCLUDED) 5 6function(get_library_version OPUS_LIBRARY_VERSION OPUS_LIBRARY_VERSION_MAJOR) 7 file(STRINGS configure.ac opus_lt_current_string 8 LIMIT_COUNT 1 9 REGEX "OPUS_LT_CURRENT=") 10 string(REGEX MATCH 11 "OPUS_LT_CURRENT=([0-9]*)" 12 _ 13 ${opus_lt_current_string}) 14 set(OPUS_LT_CURRENT ${CMAKE_MATCH_1}) 15 16 file(STRINGS configure.ac opus_lt_revision_string 17 LIMIT_COUNT 1 18 REGEX "OPUS_LT_REVISION=") 19 string(REGEX MATCH 20 "OPUS_LT_REVISION=([0-9]*)" 21 _ 22 ${opus_lt_revision_string}) 23 set(OPUS_LT_REVISION ${CMAKE_MATCH_1}) 24 25 file(STRINGS configure.ac opus_lt_age_string 26 LIMIT_COUNT 1 27 REGEX "OPUS_LT_AGE=") 28 string(REGEX MATCH 29 "OPUS_LT_AGE=([0-9]*)" 30 _ 31 ${opus_lt_age_string}) 32 set(OPUS_LT_AGE ${CMAKE_MATCH_1}) 33 34 math(EXPR OPUS_LIBRARY_VERSION_MAJOR "${OPUS_LT_CURRENT} - ${OPUS_LT_AGE}") 35 set(OPUS_LIBRARY_VERSION_MINOR ${OPUS_LT_AGE}) 36 set(OPUS_LIBRARY_VERSION_PATCH ${OPUS_LT_REVISION}) 37 set( 38 OPUS_LIBRARY_VERSION 39 "${OPUS_LIBRARY_VERSION_MAJOR}.${OPUS_LIBRARY_VERSION_MINOR}.${OPUS_LIBRARY_VERSION_PATCH}" 40 PARENT_SCOPE) 41 set(OPUS_LIBRARY_VERSION_MAJOR ${OPUS_LIBRARY_VERSION_MAJOR} PARENT_SCOPE) 42endfunction() 43 44function(check_flag NAME FLAG) 45 include(CheckCCompilerFlag) 46 check_c_compiler_flag(${FLAG} ${NAME}_SUPPORTED) 47endfunction() 48 49include(CheckIncludeFile) 50 51# This function determines if the compiler has support for SSE, SSE2, SSE4.1, AVX, 52# AVX2 and FMA. Should the target systems potentially lack SSE support, the 53# OPUS_MAY_HAVE_SSE option is recommended for use. If, however, the target system is 54# assured to support SSE, the OPUS_PRESUME_SSE option can be employed, thus 55# eliminating the necessity for an SSE runtime check. 56function(opus_detect_sse COMPILER_SUPPORT_SIMD) 57 message(STATUS "Check SIMD support by compiler") 58 check_include_file(xmmintrin.h HAVE_XMMINTRIN_H) # SSE1 59 if(HAVE_XMMINTRIN_H) 60 if(MSVC) 61 # different arch options for 32 and 64 bit target for MSVC 62 if(CMAKE_SIZEOF_VOID_P EQUAL 4) 63 check_flag(SSE1 /arch:SSE) 64 else() 65 set(SSE1_SUPPORTED 66 1 67 PARENT_SCOPE) 68 endif() 69 else() 70 check_flag(SSE1 -msse) 71 endif() 72 else() 73 set(SSE1_SUPPORTED 74 0 75 PARENT_SCOPE) 76 endif() 77 78 check_include_file(emmintrin.h HAVE_EMMINTRIN_H) # SSE2 79 if(HAVE_EMMINTRIN_H) 80 if(MSVC) 81 if(CMAKE_SIZEOF_VOID_P EQUAL 4) 82 check_flag(SSE2 /arch:SSE2) 83 else() 84 set(SSE2_SUPPORTED 85 1 86 PARENT_SCOPE) 87 endif() 88 else() 89 check_flag(SSE2 -msse2) 90 endif() 91 else() 92 set(SSE2_SUPPORTED 93 0 94 PARENT_SCOPE) 95 endif() 96 97 check_include_file(smmintrin.h HAVE_SMMINTRIN_H) # SSE4.1 98 if(HAVE_SMMINTRIN_H) 99 if(MSVC) 100 if(CMAKE_SIZEOF_VOID_P EQUAL 4) 101 check_flag(SSE4_1 /arch:SSE2) # SSE2 and above 102 else() 103 set(SSE4_1_SUPPORTED 104 1 105 PARENT_SCOPE) 106 endif() 107 else() 108 check_flag(SSE4_1 -msse4.1) 109 endif() 110 else() 111 set(SSE4_1_SUPPORTED 112 0 113 PARENT_SCOPE) 114 endif() 115 116 check_include_file(immintrin.h HAVE_IMMINTRIN_H) # AVX2 117 if(HAVE_IMMINTRIN_H) 118 if(MSVC) 119 check_flag(AVX2 /arch:AVX2) 120 else() 121 check_flag(AVX2 -mavx2 -mfma -mavx) 122 endif() 123 else() 124 set(AVX2_SUPPORTED 125 0 126 PARENT_SCOPE) 127 endif() 128 129 if(SSE1_SUPPORTED OR SSE2_SUPPORTED OR SSE4_1_SUPPORTED OR AVX2_SUPPORTED) 130 set(COMPILER_SUPPORT_SIMD 1 PARENT_SCOPE) 131 else() 132 message(STATUS "No SIMD support in compiler") 133 endif() 134endfunction() 135 136function(opus_detect_neon COMPILER_SUPPORT_NEON) 137 if(CMAKE_SYSTEM_PROCESSOR MATCHES "(arm|aarch64)") 138 message(STATUS "Check NEON support by compiler") 139 check_include_file(arm_neon.h HAVE_ARM_NEON_H) 140 if(HAVE_ARM_NEON_H) 141 set(COMPILER_SUPPORT_NEON ${HAVE_ARM_NEON_H} PARENT_SCOPE) 142 endif() 143 endif() 144endfunction() 145 146function(opus_supports_cpu_detection RUNTIME_CPU_CAPABILITY_DETECTION) 147 set(RUNTIME_CPU_CAPABILITY_DETECTION 0 PARENT_SCOPE) 148 if(OPUS_CPU_X86 OR OPUS_CPU_X64) 149 if(MSVC) 150 check_include_file(intrin.h HAVE_INTRIN_H) 151 if(HAVE_INTRIN_H) 152 # if intrin.h is available we assume __cpuid is there 153 set(RUNTIME_CPU_CAPABILITY_DETECTION 1 PARENT_SCOPE) 154 endif() 155 else() 156 include(CFeatureCheck) 157 c_feature_check(CPU_INFO_BY_ASM) 158 set(CPU_INFO_BY_ASM_SUPPORTED ${CPU_INFO_BY_ASM_SUPPORTED} PARENT_SCOPE) 159 check_include_file(cpuid.h HAVE_CPUID_H) 160 if(HAVE_CPUID_H) 161 c_feature_check(CPU_INFO_BY_C) 162 set(CPU_INFO_BY_C_SUPPORTED ${CPU_INFO_BY_C_SUPPORTED} PARENT_SCOPE) 163 endif() 164 if(CPU_INFO_BY_ASM_SUPPORTED OR CPU_INFO_BY_C_SUPPORTED) 165 set(RUNTIME_CPU_CAPABILITY_DETECTION 1 PARENT_SCOPE) 166 endif() 167 endif() 168 elseif(OPUS_CPU_ARM) 169 # ARM cpu detection is implemented for Windows and anything 170 # using a Linux kernel (such as Android). 171 if (CMAKE_SYSTEM_NAME MATCHES "(Windows|Linux|Android)") 172 set(RUNTIME_CPU_CAPABILITY_DETECTION 1 PARENT_SCOPE) 173 endif () 174 else() 175 set(RUNTIME_CPU_CAPABILITY_DETECTION 0 PARENT_SCOPE) 176 endif() 177endfunction() 178 179function(add_sources_group target group) 180 target_sources(${target} PRIVATE ${ARGN}) 181 source_group(${group} FILES ${ARGN}) 182endfunction() 183 184function(get_opus_sources SOURCE_GROUP MAKE_FILE SOURCES) 185 # read file, each item in list is one group 186 file(STRINGS ${MAKE_FILE} opus_sources) 187 188 # add wildcard for regex match 189 string(CONCAT SOURCE_GROUP ${SOURCE_GROUP} ".*$") 190 191 # find group 192 foreach(val IN LISTS opus_sources) 193 if(val MATCHES ${SOURCE_GROUP}) 194 list(LENGTH val list_length) 195 if(${list_length} EQUAL 1) 196 # for tests split by '=' and clean up the rest into a list 197 string(FIND ${val} "=" index) 198 math(EXPR index "${index} + 1") 199 string(SUBSTRING ${val} 200 ${index} 201 -1 202 sources) 203 string(REPLACE " " 204 ";" 205 sources 206 ${sources}) 207 else() 208 # discard the group 209 list(REMOVE_AT val 0) 210 set(sources ${val}) 211 endif() 212 break() 213 endif() 214 endforeach() 215 216 list(LENGTH sources list_length) 217 if(${list_length} LESS 1) 218 message( 219 FATAL_ERROR 220 "No files parsed successfully from ${SOURCE_GROUP} in ${MAKE_FILE}") 221 endif() 222 223 # remove trailing whitespaces 224 set(list_var "") 225 foreach(source ${sources}) 226 string(STRIP "${source}" source) 227 list(APPEND list_var "${source}") 228 endforeach() 229 230 set(${SOURCES} ${list_var} PARENT_SCOPE) 231endfunction() 232